Отправка данных подписи в ответ APDU - Java Card

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

Когда я пытаюсь отправить другие данные в ответ 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;
    }
}

1 ответ

Решение

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

Другие вопросы по тегам