2015-05-08 2 views
1

Я хотел бы подписать некоторые данные (массив байтов MESSAGE) на моей Java-карте и затем вернуть подпись в ответном APDU. Мой код работает нормально (или, по крайней мере, я думаю, что он делает, и он возвращает 9000) без строки apdu.sendBytes (BAS, sSignLen), но когда я раскомментирую его, я получаю неизвестную ошибку (0xC000002B (Неизвестная ошибка.)).Отправка данных подписи в ответ APDU - Java Card

Когда я пытаюсь отправить другие данные в ответ APDU, он работает безупречно.

apdu.setIncomingAndReceive(); 
Util.arrayCopyNonAtomic(MESSAGE, (short) 0, buffer, (short) 0, (short) MESSAGE.length); 
apdu.setOutgoingAndSend((short) 0, (short) MESSAGE.length); 

Вот мой код. Что я делаю не так или нет? Спасибо!

public class TestApplet extends Applet { 

    ... 

    private final static byte SIGN = (byte) 0x01; 

    ... 

    private final static byte[] MESSAGE = new byte[] { 'M', 'e', 's', 's', 'a', 'g', 'e' }; 

    final static short BAS = 0; 

    public void process(APDU apdu) { 
     if (this.selectingApplet()) 
      return; 

     byte buffer[] = apdu.getBuffer(); 

     ... 

     switch (buffer[ISO7816.OFFSET_INS]) { 
     case SIGN: 
      try { 
       ECDSAKeyPair = Secp256k1Domain.getKeyPairParameter(); 
       ECDSAKeyPair.genKeyPair(); 

       ECDSAPublicKey = (ECPublicKey) ECDSAKeyPair.getPublic(); 
       ECDSAPrivateKey = (ECPrivateKey) ECDSAKeyPair.getPrivate(); 

       ECDSASignature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false); 

       short signLen = 0; 

       byte[] signatureArray = new byte[70]; 

       ECDSASignature.init(ECDSAPrivateKey, Signature.MODE_SIGN); 
       signLen = ECDSASignature.sign(MESSAGE, BAS, (short) MESSAGE.length, signatureArray, BAS); 

       apdu.setIncomingAndReceive(); 
       Util.arrayCopyNonAtomic(signatureArray, (short) 0, buffer, (short) 0, (short) signatureArray.length); 
       apdu.setOutgoingAndSend((short) 0, (short) signatureArray.length); 
      } catch (CryptoException c) { 
       short reason = c.getReason(); 
       ISOException.throwIt((short) ((short) (0x9C00) | reason)); 
      } 

      break; 

     ... 

     return; 
    } 
} 

ответ

2

Это, вероятно, что signLen больше, чем значение Ne (неправильно называемой Le в спецификациях JavaCard). Вы также злоупотребляете значением Le значением (short) MESSAGE.length. Ne указывает максимальное количество байтов, которые, как ожидается, будут отправлены обратно.

+0

Действительно, я использовал 'Le' вместо' (short) MESSAGE.length'. Я обновил код. Спасибо! Я также думал, что проблема имеет какое-то отношение к размерам данных. Как сообщить карточке, что ответ (т. Е. Подпись) будет больше, чем значение Ne, вот как установить Ne в signLen, чтобы я мог правильно получить ответ APDU? @Maarten Bodewes – bp14

+0

Вы не можете, не спрашивая карточку/заявку. Но большинство читателей позволяют Ne быть 256 байтами (Le, кодировка Ne, должна быть «00»). Поскольку Ne - максимальный размер *, вы всегда можете установить Le до 00 для любой команды, которая ожидает откликов. –

+0

Теперь он работает. Перед подписанием я создаю массив, который является моим выходным буфером, и после подписания я копирую его содержимое в буфер. Я не знаю, почему почему буфер не работает как мой выходной буфер для подписи. Неважно. – bp14

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

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