So I have decided to hand code my own ALG_RSA_SHA256_PKCS1 function below:
Code: Select all
public final static byte[] SIGN_SHA256_ASN_TAG = new byte[]{
(byte) 0x30, (byte) 0x31, (byte) 0x30, (byte) 0x0D, (byte) 0x06,
(byte) 0x09, (byte) 0x60, (byte) 0x86, (byte) 0x48, (byte) 0x01,
(byte) 0x65, (byte) 0x03, (byte) 0x04, (byte) 0x02, (byte) 0x01,
(byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x20};
public boolean rsaSha256PKCS1Signature(Key rsaKey, byte[] data, short offset,
short length, byte[] data1, short offset1, short length1,
byte[] verifier, short vOffset, short vLength,
byte[] workBuff, short workBuffOffset, byte[] output,
short outputOffset, byte mode) {
// Calculate SHA256 of data with result offset to allow SHA256 ASN Tag to be added in front later
sha256.reset();
if (data != null && data1 != null) {
sha256.update(data1, offset1, length1);
sha256.doFinal(data, offset, length, workBuff, (short) (workBuffOffset + SIGN_SHA256_ASN_TAG.length));
} else {
sha256.doFinal(data, offset, length, workBuff, (short) (workBuffOffset + SIGN_SHA256_ASN_TAG.length));
}
// Get SHA256 ASN Tag and append to front of SHA256 result
Util.arrayCopyNonAtomic(SIGN_SHA256_ASN_TAG, (short) 0, workBuff, workBuffOffset, (short) SIGN_SHA256_ASN_TAG.length);
if (mode == Signature.MODE_SIGN) {
// Set RSA Cipher to Encrypt mode.
rsaCipher.init(rsaKey, Cipher.MODE_ENCRYPT);
// RSA Private Key encrypt ASN.1 tag + SHA256 result
rsaCipher.doFinal(workBuff, workBuffOffset, (short) 51, output, (short) outputOffset);
return true;
} else if (mode == Signature.MODE_VERIFY) {
// Set RSA Cipher to Decrypt Mode.
rsaCipher.init(rsaKey, Cipher.MODE_DECRYPT);
// RSA Public Key decrypt received ASN.1 tag + SHA256 result and put it behind the above calculated ASN.1 tag + SHA256 result
rsaCipher.doFinal(verifier, vOffset, vLength, workBuff, (short) (workBuffOffset + 51));
// Compare 51 bytes (19 bytes ASN Tag, 32 bytes SHA256 hash) from generated result and decrypted result
if (Util.arrayCompare(workBuff, workBuffOffset, workBuff, (short) (workBuffOffset + 51), (short) 51) == 0) {
return true;
}
}
return false;
}
When executed on Feitian's C21C and NXP JCOP 2.4.2 R3 J3E081_M64 smart card chips, they both work when using a Java desktop JCE to read the signature and verify.
Anyone can replicate the above problem on their A22CR cards ?