JavaCard> подписать и проверить - PullRequest
2 голосов
/ 08 января 2012

Может кто-нибудь дать мне небольшой совет о том, как сделать подпись с javacard и проверить ее?Я думаю, что я делаю что-то не так с генерацией и проверкой подписи:

...

SignatureMessageRecovery sig;

...

private Cardlet(byte[] bArray, short bOffset, byte bLength) {
    /* Generate our RSA key */
    keyPair = new KeyPair(KeyPair.ALG_RSA, (short) 512);
    keyPair.genKeyPair();
    /* signature buffer is 64 + 2 (offset + length) */
    sigBuff = JCSystem.makeTransientByteArray((short) (SIG_LENGTH + 2), JCSystem.CLEAR_ON_DESELECT);
    sig = (SignatureMessageRecovery) Signature.getInstance(Signature.ALG_RSA_SHA_ISO9796_MR, false);
}

...

private void insCryptoSigne(APDU apdu) {

    byte[] buffer = apdu.getBuffer();
    short bytesRead = apdu.setIncomingAndReceive();
    short[] m1Data = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_DESELECT);

    sigLen = sig.sign(buffer, ISO7816.OFFSET_CDATA, bytesRead, sigBuff, (short) 0, m1Data, (short) 0);
    // set m1Length into sigBuff array
    sigBuff[sigLen] = (byte) ((short) (m1Data[(short) 0] & ((short) 0xFF00)) >> ((short) 8));
    sigBuff[(short) (sigLen + 1)] = (byte) (m1Data[(short) 0] & ((short) 0x00FF));

    apdu.setOutgoing();
    apdu.setOutgoingLength((short) (sigLen + 2));// The extra 2 bytes for
    apdu.sendBytesLong(sigBuff, (short) 0, (short) (sigLen + 2));
}

НА стороне Java Я уже получил открытый ключ, сохранил его в локальном файле как X509Certificate.Уверены, что они совпадают с модулем и показателем степени, которые кажутся одинаковыми как в сертификате, так и в карточке.

FileInputStream certis = new FileInputStream(cert);
X509Certificate c1 = new X509Certificate(certis);

...

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] testsig = new byte[64];
System.arraycopy(raw_signature,0, testsig, 0, 64);
Signature signature = Signature.getInstance("SHA1withRSA", "BC");
signature.initVerify(c1.getPublicKey());
System.out.println(c1.getPublicKey());
System.out.println(signature);
System.out.println(file_data.length+":> "+new String(file_data));
signature.update(file_data);
System.out.println("VERIFY > "+signature.verify(testsig)+" <");

Результат ложный: (* ​​1020*

Спасибо и всего наилучшего Тури

1 Ответ

1 голос
/ 08 января 2012

Для начала вы используете две отдельные функции подписи.Более старый ISO9796 довольно отличается от формата подписи PKCS # 1, который используется, если вы указываете "SHA1withRSA" на стороне Java.Вам действительно нужно восстановление сообщений?В настоящее время он в основном используется для проверяемых сертификатами карт (, если используется ).

Просто используйте Signature и ALG_RSA_SHA_PKCS1 вместо SignatureMessageRecovery и ALG_RSA_SHA_ISO9796_MR на стороне карты Java..

Если вы хотите восстановить сообщение, вам, возможно, придется использовать библиотеку Bouncy Castle на стороне Java (и даже в Bouncy немного сложно заставить ее работать правильно).

...