Как вы сказали в своем ответе, проблема кода является то, что вы прошли неправильные параметры метода doFinal (byte[] inBuff, short inOffset, short inLength,byte[] outBuff, short outOffset)
.
Но пример кода, который вы используете, кажется очень плохим. Есть причины, по которым я называю это плохо написанным:
1- Он использовал динамические переменные в методе, который называется так много раз. Динамические переменные - это те, кто создал ключевое слово new
. Эти переменные будут выделены в EEPROM. Зашифрование в EEPROM действительно медленное, а не ОЗУ, и оно также имеет ограниченные операции записи стирания перед ним wear out, поэтому настоятельно рекомендуется использовать ОЗУ вместо EEPROM в случаях, когда вам не нужно делиться данными между разными САПР (карта Reader). А также потому, что в Java-карте нет обязательного/автоматического сборщика мусора, не указывайте разные динамические переменные повторяющиеся, используйте один глобальный вместо этого (переменная класса или переменная экземпляра вместо локальных переменных).
2- Как int
тип данных является необязательным JavaCards, вы должны попробовать использовать short
и byte
как можно больше, и вы также должны отбрасывать все значения этих типов, чтобы предотвратить подписанное/неподписанных проблемы.
Наконец, я предоставить вам развитую версию программы:
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);
}
}
}
Он работает, как показано ниже:
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
Любое предложение сделать выше программу более эффективной радушен мне.
0x6F00 является своего рода «RuntimeException». Это может быть любая ошибка в вашем апплете. Запустите апплет на симуляторе, чтобы узнать, что произойдет. – erickson
привет там erickson. Я уже понял, что происходит с моим кодом. Кажется, я неправильно понял функцию doFinal. Я меняю входные переменные на doFinal (ввод, (короткий) 0, len, buffer, (short) 0). – Jujumancer
HectorIrvinPunzalan, вы должны ответить на свой вопрос этой информацией или попросить @erickson сделать это за вас. Вопросы с ответами помогают другим людям в сообществе: вопросы с ответами * в комментариях * обычно не полезны для других. Я рад, что вы решили свою проблему! –