I’m developing a Visual C++ application that uses MS CryptoAPI to encrypt a message and then sends encrypted message to a javacard (Cyberflex Access e-gate). The smartcard receives the message, decrypts it and send the decrypted message to Visual C++ application so vc++ application can compare what it receives to the original message and know if smartcard that received encrypted message is that should be because only one can decrypt the message.
I have developed a Java application that emulates Visual C++ application and encryption (off the card) and decryption (on the card) works… so I think that applet on the card is ok.
Moreover, I know that Java works in big endian and Visual C++ in little Indian so bytes have to be inverted. I know that modulus of the public key on card is the following:
0xAC,0x9B,0xFF,0x47,0xCF,0x0B,0x77,0x22,<br />
0x19,0x2A,0xBC,0x23,0x25,0x11,0x8D,0x3A,<br />
0x4C,0xAC,0xB5,0xB1,0x0C,0x50,0x5E,0x5E,<br />
0xC7,0x5E,0xC0,0x66,0xE5,0xA9,0x1B,0x6E,<br />
0xD2,0xE0,0xF7,0xA4,0x11,0x96,0x77,0x86,<br />
0x29,0xC1,0xD9,0xCC,0x30,0xCE,0x85,0x8D,<br />
0x37,0xFE,0x3E,0xFA,0x84,0x8B,0x26,0xB5,<br />
0xA0,0x44,0xCF,0x09,0x66,0x0A,0xCF,0x52,<br />
0xDF,0xBF,0xEE,0x7D,0x49,0xD6,0x5C,0xFE,<br />
0x0B,0x8C,0x16,0x0E,0x3F,0x5D,0xEA,0x23,<br />
0xB4,0x8A,0xDD,0x83,0x88,0x02,0xDC,0x1A,<br />
0xB9,0xED,0xB1,0x7A,0x88,0xFF,0x2F,0x44,<br />
0xDD,0x58,0xE8,0xFA,0x00,0x42,0x60,0x8E,<br />
0x77,0xC7,0x61,0xEA,0xFE,0x0E,0x8D,0xE9,<br />
0xC4,0xDD,0x60,0x3F,0x3C,0x9A,0x78,0x4F,<br />
0x93,0x45,0x2D,0x00,0xEC,0x59,0x04,0x95
I get this using APDU Manager in the Cyberflex Access SDK 4.5… so I have tried with that and with the inverted modulus:
0x95,0x04,0x59,0xEC,0x00,0x2D,0x45,0x93,<br />
0x4F,0x78,0x9A,0x3C,0x3F,0x60,0xDD,0xC4,<br />
0xE9,0x8D,0x0E,0xFE,0xEA,0x61,0xC7,0x77,<br />
0x8E,0x60,0x42,0x00,0xFA,0xE8,0x58,0xDD,<br />
0x44,0x2F,0xFF,0x88,0x7A,0xB1,0xED,0xB9,<br />
0x1A,0xDC,0x02,0x88,0x83,0xDD,0x8A,0xB4,<br />
0x23,0xEA,0x5D,0x3F,0x0E,0x16,0x8C,0x0B,<br />
0xFE,0x5C,0xD6,0x49,0x7D,0xEE,0xBF,0xDF,<br />
0x52,0xCF,0x0A,0x66,0x09,0xCF,0x44,0xA0,<br />
0xB5,0x26,0x8B,0x84,0xFA,0x3E,0xFE,0x37,<br />
0x8D,0x85,0xCE,0x30,0xCC,0xD9,0xC1,0x29,<br />
0x86,0x77,0x96,0x11,0xA4,0xF7,0xE0,0xD2,<br />
0x6E,0x1B,0xA9,0xE5,0x66,0xC0,0x5E,0xC7,<br />
0x5E,0x5E,0x50,0x0C,0xB1,0xB5,0xAC,0x4C,<br />
0x3A,0x8D,0x11,0x25,0x23,0xBC,0x2A,0x19,<br />
0x22,0x77,0x0B,0xCF,0x47,0xFF,0x9B,0xAC
Next, I show what I do to encrypt and send the message to the smartcard.
First of all, I initialise the public key and the message:
<code>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
};
BYTE* pbContent;
DWORD cbContent;
pbContent = (BYTE*) "Security is our business...";
cbContent = strlen((char *)pbContent)+1;
HCRYPTPROV hProv;
HCRYPTKEY hMyKey;</code>
Now I acquire context:
if(!CryptAcquireContext(
&hProv,
NULL,
MS_DEF_PROV,
PROV_RSA_FULL,
NULL)) {
MessageBox("CryptAcquireContext failed.", "Error", MB_OK);
}
Everything seems to be ok because I don’t get error MessageBox so I import public key:
if (CryptImportKey (hProv, rsaKeyBlob, sizeof(rsaKeyBlob), 0,0, &hMyKey))
{
MessageBox("Public key import success.", "OK", MB_OK);
}
else
{
MessageBox("Public key import failed.", "Error", MB_OK);
exit(1);
}
Once again, it seems to be ok because I get “Public key import success”. So I can start to encrypt the message:
BYTE* pbEncryptedBlob;
DWORD cbEncryptedBlob;
CryptEncrypt(hMyKey, 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(hMyKey, 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);
}
Again, everything seems to be ok because I get “Memory has been allocated for the encrypted BLOB” and “The size of encrypted message is 128 bytes…”
Now I only should have to send it to the card to be decrypted:
try {
this->m_sCard = this->m_sIOP.Connect("axalto e-gate 0", false);
this->m_VisaOP = this->m_sCard->GetVisaOP();
BYTE aid[] = {0x55,0x44,0x33,0x22,0x11, 0x00, 0x22};
try {
this->m_VisaOP->SelectAID(aid,7);
}
catch(scu::Exception const &e)
{
MessageBox( e.Description(), "Error", MB_OK);
}
} catch(scu::Exception const &e) {
MessageBox( e.Description(), "Info", MB_OK);
}
this->bCLA = (byte)0x68;
this->bINS = (byte)0x30;
this->bP1 = (byte)0;
this->bP2 = (byte)0;
BYTE auxB[] = {0x00,0x00, 0x00,0x00};
try
{
this->m_sCard->SendCardAPDU(this->bCLA,this->bINS,this->bP1,this->bP2,4,auxB,NULL,NULL);
}
catch(iop::CSmartCard::Exception const &e)
{
WORD sw = e.Status();
if (sw == 0x6300) {
MessageBox( "Wrong PIN.", "Error", MB_OK);
}
else {
MessageBox( "Unknown error.", "Info", MB_OK);
}
}
Until here I don’t get any error.
this->bCLA = (byte)0x68;
this->bINS = (byte)0x42;
this->bP1 = (byte)0;
this->bP2 = (byte)0;
BYTE bDataBufferAux[1024];
memset(bDataBufferAux,'\0',1024);
BYTE* auxBuffer;
auxBuffer = pbEncryptedBlob;
for (int i=0; i<cbEncryptedBlob; i++){
this->bDataBuffer[i] = auxBuffer[i];
}
try
{
this->m_sCard->SendCardAPDU(this->bCLA,this->bINS,this->bP1,this->bP2,128,this->bDataBuffer,28,bDataBufferAux);
}
catch(iop::CSmartCard::Exception const &e)
{
WORD sw = e.Status();
if (sw == 0x6300) {
MessageBox("Wrong PIN.", "Error", MB_OK);
}
else if (sw == 0x6F00){
MessageBox("SW_UNKNOWN", "Error", MB_OK);
}
else {
MessageBox("Unknown error.", "Info", MB_OK);
}
}
Here I get 0x6F00 error and because of that I need help.
I would be grateful if someone helps me. Thanks in advance.
Regards,
Manolo.
|