У меня есть следующая функция в апплете javacard, которая должна принимать вызов от хост-приложения, подписывать его и возвращать на хост через связь apdu command-response.
private void sign(APDU apdu) {
if(!pin.isValidated())ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
else{
byte[] buffer = apdu.getBuffer();
byte [] output = new byte [20];
short length = 20;
short x =0;
Signature signature =Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1, false);
signature.init(privKey, Signature.MODE_SIGN);
short sigLength = signature.sign(buffer, offset,length, output, x);
//This sequence of three methods sends the data contained in
//'serial' with offset '0' and length 'serial.length'
//to the host application.
apdu.setOutgoing();
apdu.setOutgoingLength((short)output.length);
apdu.sendBytesLong(output,(short)0,(short)output.length);
}
}
хост вычисляет запрос следующим образом и отправляет его в апплет javacard для подписи:
//produce challenge
SecureRandom random = SecureRandom . getInstance( "SHA1PRNG" ) ;
byte [ ]bytes = new byte [ 20 ] ;
random . nextBytes ( bytes) ;
CommandAPDU challenge;
ResponseAPDU resp3;
challenge = new CommandAPDU(IDENTITY_CARD_CLA,SIGN_CHALLENGE, 0x00, 0x00,bytes ,20 );
resp3= c.transmit(challenge);
if(resp3.getSW()==0x9000) {
card_signature = resp2.getData();
String s = new String(card_signature);
System.out.println("signature " + s);
}else System.out.println("Challenge signature error: " + resp3.getSW());
Как видите, я проверяю как успешное, так и неудачное подписание, но распечатываю следующее:
Challenge signature error:28416
Где именно я ошибаюсь?Могу ли я получить вызов ошибочным способом с помощью `byte [] buffer = apdu.getBuffer ();или моя подпись не так?