我编写了一个程序,在我的Java卡上使用RSA公钥加密10
字节随机数。每次卡接收到APDU命令时生成随机数,由于我的applet中相关的密码对象块大小为2048位,因此我在这个10
字节随机数的末尾添加242字节的0x00
,使其长度为256
字节。
问题是,有时响应是一个具有05
值的加密异常。如你所知,正如JC API文档中提到的:
0x05
= ILLEGAL_USEpublic static final short ILLEGAL_USE
此原因代码用于表示签名或密码算法没有填充传入消息和输入消息不对齐。
由于输入长度在我的applet中是固定的,我无法解决我的问题!
下面是我的applet的相关部分:
protected final void getEncChallenge(APDU apdu) {
random.generateData(generatedChall, (short) 0, (short) 10);
initAsymCipher(ENTITY_BOB, MODE_ENC);
Util.arrayCopy(generatedChall, (short) 0, transientData, (short) 0, (short) 10);
Util.arrayFillNonAtomic(transientData, (short) 10, (short) 246, (byte) 0x00);
rsaCrypto(transientData, persistentData);
apdu.setOutgoing();
apdu.setOutgoingLength((short) 256);
apdu.sendBytesLong(persistentData, (short) 0, (short) 256);
}
protected final void rsaCrypto(byte[] inData, byte[] outData) {
try{
asymCipher.doFinal(inData, (short) 0, (short) 256, outData, (short) 0);
}catch(CryptoException e){
short reason = e.getReason();
ISOException.throwIt((short)(0x6d00 | reason));
}
}
下面是响应:
transientData ---> APDU Response
---------------------------------
80 ..(Eight Random Bytes).. BD ..(246 bytes of "0x00").. ---> OK (i.e. 256 byte encrypted data)
EO ..(Eight Random Bytes).. 64 ..(246 bytes of "0x00").. ---> 6D05
02 ..(Eight Random Bytes).. B3 ..(246 bytes of "0x00").. ---> OK
CB ..(Eight Random Bytes).. 35 ..(246 bytes of "0x00").. ---> 6D05
17 ..(Eight Random Bytes).. 97 ..(246 bytes of "0x00").. ---> OK
0C ..(Eight Random Bytes).. 0C ..(246 bytes of "0x00").. ---> OK
D3 ..(Eight Random Bytes).. 91 ..(246 bytes of "0x00").. ---> 6D05
86 ..(Eight Random Bytes).. E2 ..(246 bytes of "0x00").. ---> OK
C2 ..(Eight Random Bytes).. 23 ..(246 bytes of "0x00").. ---> 6D05
有谁知道我的小程序出了什么问题吗? 你在错误的一边填充。RSA工作在大端编码数到模数大小。通常的填充机制(通常的RSA安全性所需要的)通过左填充来工作,其值严格小于模数。
所以基本上你的填充挑战被视为一个编码的数字,当转换时,它有时比模数大。当这种情况发生时,RSA例程将不接受它。
在左边填充零字节应该可以解决这个问题。或者,您可以确保挑战的最高阶位被掩码为零(& 0x7F
)。