Wie Sie in Ihrer Antwort, sagte, das Problem des Codes ist, dass Sie falsche Parameter an die doFinal (byte[] inBuff, short inOffset, short inLength,byte[] outBuff, short outOffset)
Methode übergeben.
Aber der Beispielcode, den Sie verwenden, scheint wirklich schlecht. Es gibt Gründe, die ich es schlecht schreibe:
1- Es verwendete dynamische Variablen in einer Methode, die so oft aufgerufen wird. Dynamische Variablen sind diejenigen, die mit dem Schlüsselwort new
erstellt wurden. Diese Variablen werden im EEPROM zugewiesen. Das Schreiben im EEPROM ist eher langsam als RAM und es hat auch eine begrenzte Lösch-Schreib-Operationen, bevor es wear out, so ist es sehr empfehlenswert, RAM anstelle von EEPROM zu verwenden, falls Sie die Daten nicht zwischen verschiedenen CAD (Card Leser) Sitzungen. Und da es in Java Card auch keinen obligatorischen/automatischen Garbage Collector gibt, sollten Sie nicht verschiedene dynamische Variablen repetitiv definieren, sondern stattdessen ein globales verwenden (Klassenvariable oder Instanzvariable anstelle von lokalen Variablen).
2- Als int
Datentyp in Javacards optional ist, müssen Sie versuchen, short
und byte
so viel wie möglich zu verwenden, und Sie müssen auch alle Werte auf diese Art werfen mit/ohne Vorzeichen Probleme zu verhindern.
Schließlich biete ich Ihnen eine weiterentwickelte Version des Programms:
package soQusetion;
import javacard.framework.*;
import javacard.security.AESKey;
import javacard.security.KeyBuilder;
import javacardx.crypto.Cipher;
public class SOQ1 extends Applet {
Cipher aesCipher;
AESKey aesKey;
//Two different types of memory for different usage. each one has 16 (= 0x10) byte capacity.
private byte[] volatileMem;
private byte[] nonVolatileMem;
//INS value for APDU command
public static final byte INS_SET_KEY = 0x10;
public static final byte INS_ENCRYPT = 0x20;
public static final byte INS_DECRYPT = 0x30;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new SOQ1();
}
protected SOQ1() {
volatileMem = JCSystem.makeTransientByteArray((short) 0x10, JCSystem.CLEAR_ON_DESELECT);
nonVolatileMem = new byte[(short) 0x10];
aesCipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_ECB_NOPAD, false);
aesKey = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);
register();
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
apdu.setIncomingAndReceive();
if (buffer[ISO7816.OFFSET_LC] != (byte) 0x10) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
switch (buffer[ISO7816.OFFSET_INS]) {
case INS_SET_KEY:
aesKey.setKey(buffer, ISO7816.OFFSET_CDATA);
break;
case INS_ENCRYPT:
aesCipher.init(aesKey, Cipher.MODE_ENCRYPT);
aesCipher.doFinal(buffer, ISO7816.OFFSET_CDATA, (short) 0x10, volatileMem, (short) 0x00);
Util.arrayCopyNonAtomic(volatileMem, (short) 0x00, buffer, (short) 0x00, (short) 0x10);
apdu.setOutgoingAndSend((short) 0x00, (short) 0x10);
break;
case INS_DECRYPT:
aesCipher.init(aesKey, Cipher.MODE_DECRYPT);
aesCipher.doFinal(buffer, ISO7816.OFFSET_CDATA, (short) 0x10, volatileMem, (short) 0x00);
Util.arrayCopyNonAtomic(volatileMem, (short) 0x00, buffer, (short) 0x00, (short) 0x10);
apdu.setOutgoingAndSend((short) 0x00, (short) 0x10);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
}
Es wie unten funktioniert:
Select Applet begin...
Select Applet successful.
//Loading AES Key APDU Command
Send: 00 10 00 00 10 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 00
Recv: 90 00
//Encrypt APDU Command
Send: 00 20 00 00 10 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 00
Recv: 62 F6 79 BE 2B F0 D9 31 64 1E 03 9C A3 40 1B B2 90 00
//Decrypt APDU Command
Send: 00 30 00 00 10 62 F6 79 BE 2B F0 D9 31 64 1E 03 9C A3 40 1B B2 00
Recv: 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 90 00
Jeder Vorschlag, das obige Programm effizienter zu machen, ist mir willkommen.
0x6F00 ist eine Art wie 'RuntimeException'. Es könnte sich um einen Fehler in Ihrem Applet handeln. Führen Sie Ihr Applet auf einem Simulator aus, um zu sehen, was passiert. – erickson
Hallo Erickson. Ich habe bereits herausgefunden, was mit meinem Code passiert. Scheint, dass ich die Funktion doFinal falsch verstanden habe. Ich ändere die Eingabevariablen in doFinal (Eingabe, (kurz) 0, len, Puffer, (kurz) 0). – Jujumancer
HectorIrvinPunzalan, Sie sollten Ihre Frage mit diesen Informationen beantworten oder @erickson bitten, dies für Sie zu tun. Fragen mit Antworten helfen anderen Menschen in der Gemeinschaft: Fragen mit Antworten * in den Kommentaren * sind für andere normalerweise nicht nützlich. Ich bin froh, dass du dein Problem gelöst hast! –