I have a smartcard Cyberflex Access e-gate and I have developed for it an applet that receives an encrypted text (encrypted by a visual c++ application, using CryptoAPI), decrypts the text and returns the decrypted text signed. The problem is that I don’t get visual c++ application verifies signed text.
On card I have the following code:
byte apduBuffer[] = apdu.getBuffer();
short byteRead = (short)(apdu.setIncomingAndReceive());
cipherRSA = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false);
cipherRSA.init(privateKey, Cipher.MODE_DECRYPT);
cipherRSA.doFinal(apduBuffer,(short)APDUDATA, byteRead, apduBuffer, (short)0);
cipherRSA.init(privateKey, Cipher.MODE_ENCRYPT);
short outbytes;
outbytes = cipherRSA.doFinal(apduBuffer,(short)APDUDATA, (short) 1, apduBuffer, (short)0);
apdu.setOutgoing();
apdu.setOutgoingLength((short)outbytes);
apdu.sendBytes((short) 0, (short) outbytes);
On visual c++ application I have the following code:
pbContent = (BYTE*) "Security is our business...";
cbContent = strlen((char *)pbContent)+1;
cbEncryptedBlob = cbContent;
if(!CryptAcquireContext(
&hProv,
NULL,
MS_DEF_PROV,
PROV_RSA_FULL,
NULL)) {
MessageBox("CryptAcquireContext failed.", "Error", MB_OK);
}
if (!CryptImportKey (hProv, rsaKeyBlob, sizeof(rsaKeyBlob), 0,0, &hMiKey))
{
MessageBox("Public key import failed.", "Error", MB_OK);
exit(1);
}
CryptEncrypt(hMiKey, 0, TRUE, 0, NULL, &cbEncryptedBlob, cbContent);
if(pbEncryptedBlob = (BYTE*)malloc(cbEncryptedBlob))
{
MessageBox("Memory has been allocated for the encrypted BLOB.", "Info", MB_OK);
memset(pbEncryptedBlob, '\0', cbEncryptedBlob);
memcpy(pbEncryptedBlob, pbContent, cbContent);
}
else
{
MessageBox("Memory allocation error while encrypting.", "ERROR", MB_OK);
}
if(!CryptEncrypt(hMiKey, NULL, TRUE, NULL, pbEncryptedBlob, &cbContent, cbEncryptedBlob)) {
MessageBox("CryptEncrypt failed.", "Error", MB_OK);
} else {
char* EncryptedString = new char[(cbEncryptedBlob * 2) +1];
ByteToStr(cbEncryptedBlob, pbEncryptedBlob, EncryptedString);
wsprintf(informacion,"The size of encrypted message is %d bytes.\n%s",cbEncryptedBlob,EncryptedString);
MessageBox(informacion, "Info", MB_OK);
}
Now I send pbEncryptedBlob (reversed because of little-big endian issue) to the card and I receive a BYTE[128]. That array is what I try to verify with the public key visual c++ application has read from card at the beginning.
if(!CryptDecrypt(hMyKey, NULL, TRUE, NULL, message, &lengthMsg)) {
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
wsprintf(informacion, "failed with error %d: %s", dw, lpMsgBuf);
MessageBox(informacion, "Error", MB_OK);
LocalFree(lpMsgBuf);
}
I get “Bad key” error here.
hMyKey comes from importing this byte array:
BYTE rsaKeyBlob[] = {
0x06,
0x02,
0x00,0x00,
0x00,0xa4,0x00,0x00,
0x52,0x53,0x41,0x31,
0x00,0x04,0x00,0x00,
0x01,0x00,0x01,0x00,
0x95,0x04,0x59,0xEC,0x00,0x2D,0x45,0x93,
0x4F,0x78,0x9A,0x3C,0x3F,0x60,0xDD,0xC4,
0xE9,0x8D,0x0E,0xFE,0xEA,0x61,0xC7,0x77,
0x8E,0x60,0x42,0x00,0xFA,0xE8,0x58,0xDD,
0x44,0x2F,0xFF,0x88,0x7A,0xB1,0xED,0xB9,
0x1A,0xDC,0x02,0x88,0x83,0xDD,0x8A,0xB4,
0x23,0xEA,0x5D,0x3F,0x0E,0x16,0x8C,0x0B,
0xFE,0x5C,0xD6,0x49,0x7D,0xEE,0xBF,0xDF,
0x52,0xCF,0x0A,0x66,0x09,0xCF,0x44,0xA0,
0xB5,0x26,0x8B,0x84,0xFA,0x3E,0xFE,0x37,
0x8D,0x85,0xCE,0x30,0xCC,0xD9,0xC1,0x29,
0x86,0x77,0x96,0x11,0xA4,0xF7,0xE0,0xD2,
0x6E,0x1B,0xA9,0xE5,0x66,0xC0,0x5E,0xC7,
0x5E,0x5E,0x50,0x0C,0xB1,0xB5,0xAC,0x4C,
0x3A,0x8D,0x11,0x25,0x23,0xBC,0x2A,0x19,
0x22,0x77,0x0B,0xCF,0x47,0xFF,0x9B,0xAC
};
Can I decrypt a message encrypted with the private key using public key in visual c++?
Do I have to use any special function to do it or I can do it like I do it in java (if I encrypt with private key, everyone can decrypt with associate public key)?
|