2016-04-20 5 views
2

Я новичок в программировании на Java. Я увидел пример использования метода шифрования AES для Java-карт и смог создать и установить апплет. Когда я пытаюсь связаться с апплетом, он возвращает сообщение об ошибке 6F00. Что я делаю не так?Шифрование карты Java с использованием AES возвращает 6F00

Вот пример моего кода:

private void SendData(APDU apdu) 
{ 

    aesKeyTrial= (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false); 
    byte[] outBuffer; 
    outBuffer = new byte[16]; 
    byte[] trialKey; 
    trialKey = new byte[16]; 
    byte[] input = {(byte)0x44,(byte)0x22,(byte)0x33,(byte)0x44,(byte)0x55,(byte)0x66,(byte)0x77,(byte)0x88,(byte)0x99,0x10,(byte)0xA2, 0x35, (byte)0x5E,0x15,0x16,0x14}; 
    byte[] key = {0x2d, 0x2a, 0x2d, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x41, 0x43, 0x4f, 0x44, 0x45, 0x2d, 0x2a, 0x2d}; 
    byte[] buffer = apdu.getBuffer(); 
    short len = (short) input.length; 


    aesKeyTrial.setKey(trialKey,(short)0); 
    if(len<=0||len%16!=0) 
    { 
     ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); 
    } 
    aesCipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false); 
    aesCipher.init(aesKeyTrial, Cipher.MODE_ENCRYPT); 
    aesCipher.doFinal(input, ISO7816.OFFSET_CDATA, len, outBuffer, (short)0); 
    Util.arrayCopyNonAtomic(input, (short)0, buffer, (short)0, (short)len); 
    apdu.setOutgoing(); 
    apdu.setOutgoingLength(len); 
    apdu.sendBytes((short) 0, (short)len); 
} 

Тот, который я пытаюсь зашифровать это «вход».

+0

0x6F00 является своего рода «RuntimeException». Это может быть любая ошибка в вашем апплете. Запустите апплет на симуляторе, чтобы узнать, что произойдет. – erickson

+0

привет там erickson. Я уже понял, что происходит с моим кодом. Кажется, я неправильно понял функцию doFinal. Я меняю входные переменные на doFinal (ввод, (короткий) 0, len, buffer, (short) 0). – Jujumancer

+0

HectorIrvinPunzalan, вы должны ответить на свой вопрос этой информацией или попросить @erickson сделать это за вас. Вопросы с ответами помогают другим людям в сообществе: вопросы с ответами * в комментариях * обычно не полезны для других. Я рад, что вы решили свою проблему! –

ответ

3

Как вы сказали в своем ответе, проблема кода является то, что вы прошли неправильные параметры метода 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 

Любое предложение сделать выше программу более эффективной радушен мне.

+0

Спасибо за предоставление развитого кода. Изучит ваш код и изучит его. Я ценю помощь! Благодаря! – Jujumancer

+0

Возвращаемое значение для загрузки AES Key Команда APDU: 'CLA: 00, INS: 0a, P1: 00, P2: 00, Lc: 17, 00, 0b, 16, 21, 2c, 37, 42, 4d, 58, 63 , 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 00, Le: 00, SW1: 69, SW2: 99'. – Niyojan

+0

И вы выбираете апплет? \ – Niyojan

2

Привет, я узнал, что случилось с моей ошибкой или что не так с моим кодом. Я неправильно понял функцию doFinal, и она испортила то, что должно быть установлено на карточке.

Вот новый и чистый код:

Cipher aesCipher; 
    AESKey aesKeyTrial; 
    aesKeyTrial= (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_AES_128, false); 
    byte[] buffer = apdu.getBuffer(); 
    byte[] aesKey; 
    aesKey = new byte[16]; 
    byte[] input = {(byte)0x11,(byte)0x22,(byte)0x33,(byte)0x44,(byte)0x55,(byte)0x66,(byte)0x77,(byte)0x88,(byte)0x99,0x10,(byte)0xA2, 0x35, (byte)0x5E,0x15,0x16,0x14}; 
    byte[] key = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26}; 

    short len = (short) input.length; 
    if (len <= 0 || len % 16 != 0) 
    { 
     ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); 
    } 

    aesKeyTrial.setKey(key,(short)0); 
    aesCipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_ECB_NOPAD, false); 
    aesCipher.init(aesKeyTrial, Cipher.MODE_ENCRYPT); 
    aesCipher.doFinal(input, (short)0, len, buffer, (short)0); 
    apdu.setOutgoingAndSend((short)0, len); 

 Смежные вопросы

  • Нет связанных вопросов^_^