RSA Encrytion lanza una excepción de forma intermitente en JavaCard
cryptography (1)
He escrito un programa para encriptar números aleatorios de 10
bytes usando una clave pública RSA en mi Java Card. El número aleatorio se genera cada vez que la tarjeta recibe ese comando APDU, y como el tamaño del bloque del objeto cifrado relacionado es 2048 bit en mi applet, añado 242 bytes de 0x00
al final de este número aleatorio de 10
bytes para convertirlo en 256
bytes longitud.
El problema es que a veces la respuesta es una Excepción Crypto con valor 05
. Como sabe, y como documentos de JC API mencionados:
0x05
= ILEGAL_USOpúblico estático final corto ILLEGAL_USE
Este código de razón se usa para indicar que el algoritmo de firma o cifrado no carga el mensaje entrante y el mensaje de entrada no está alineado con bloques.
Como la longitud de entrada está fija en mi applet, no puedo resolver mi problema.
Aquí está la parte relacionada de mi 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));
}
}
Y aquí está la respuesta:
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
¿Alguien tiene alguna idea de qué pasa con mi applet?
Estás acolchonado en el lado equivocado. RSA funciona con números codificados en big endian hasta el tamaño del módulo. Los mecanismos de relleno usuales (que se requieren para la seguridad RSA habitual) funcionan con relleno izquierdo , a un valor estrictamente más pequeño que el módulo.
Así que, básicamente, su desafío acolchado se ve como un número codificado, y cuando se convierte, a veces es más grande que el módulo. Cuando eso sucede, la rutina de RSA no lo aceptará.
Rellenar los cero bytes a la izquierda debería solucionar esto. Alternativamente, puede asegurarse de que el bit de mayor orden del desafío esté enmascarado a cero ( & 0x7F
).