Decrypt message using Javacard fails
I have a JCOP-31-card which generates a RSA-Keypair. It sends the publickey's modulos and the exponent to my client application. So far, no problem. My client application now uses the (from mod and exp) new generated public key to encrypt a string. Now I am trying to send this string to my card, to decrypt it, but i think my APDU is wrong. My command looks like this:
0x00, 0x70, 0x00,0x00,(byte)0x80
After this I append the bytes of the encrypted string (128 bytes long).
After that I am using the following to send:
rc = reader.CT_Data((char) 1, (byte)0, (byte)2, decryptCommand.length, (byte[])decryptCommand, (char) lr, rsp);
But the only thing I get back is "6c 01", as if there would be only 1 byte of data available.
Regards,
Susanne
# 1
Assuming you are doing a case 2 or case 4....For 6C 'XX' you MUST resend the command after setting Le equal to XX received from the card before any other command is sent.
# 2
Mmh, I am not sure if I understand. I guess it is a case 4. I am sending an encrypted string and want to receive the decrypted one in the response.
So I corrected (?) my command and added at the end the expected length (le). I tried several values as le, but none changed the response "6c 01".
What did you mean with "resend"?
Regards,
Susanne
# 3
Your card is configured to T=0. If you look into ISO 7816-3, T=0, you will see that the reader sends first just the header information. Your command APDU has Lc=01 --> card answers '6C01' = 'gimme the one byte' --> reader then sends the data.
Normally this is done by the reader firmware or in the reader driver. Are you using a transparent reader?
# 4
I am using a Kobil Kaan Advanced Reader and a JCOP-31 Card, which should use T=1...is there a way to change the configuration to use T=1 and not T=0 ?Regards,Susanne
# 5
If you're sure that your card uses T=1, then the only possibility is that the '6C01' is generated by your applet.
# 6
I am sure, that it uses T=1, because on connection it says:ATR: T=1, FI=1/DI=8 (31clk/etu), N=0, IFSC=254, BWI=4/CWI=5, Hist="JCOP31V22"So I do not now, where the error comes from.Message was edited by: susikaufmann
# 7
Can you post the applet source code? It might be the applet is returning '6C01'.
# 8
The Javacard-Applet calls this method:
private void decrypt(APDU apdu)
{
short byteRead = (short) (apdu.setIncomingAndReceive());
cipher.init((RSAPublicKey)keypair.getPrivate(), Cipher.MODE_DECRYPT);
short outbytes;
byte[] apduBuffer = apdu.getBuffer();
outbytes = cipher.doFinal(apduBuffer,(short)ISO7816.OFFSET_CDATA, byteRead, apduBuffer, (short)ISO7816.OFFSET_CDATA);
apdu.setOutgoing();
apdu.setOutgoingLength(outbytes);
apdu.sendBytesLong(apduBuffer, (short)ISO7816.OFFSET_CDATA, (short)outbytes);
}
Regards,
Susanne
P.S.: If needed I can post more of the applet-code, but I think this is the important part.
# 9
First, I hate beating a dead horse, but did u search the forum first ? This enc/dec has been answered a million times over.....if you search you would see a huge posting of sample code !!!
Second..why are you casting a getPrivate to a public ?
cipher.init((RSAPublicKey)keypair.getPrivate(), Cipher.MODE_DECRYPT);
should read
cipher.init((RSAPrivateKey)keypair.getPrivate(), Cipher.MODE_DECRYPT);
Third, are you sure of the RSA Private key ? A lot of vendors use CRT
# 10
Sorry, my mistake. I now use
cipher.init((RSAPrivateCrtKey)keypair.getPrivate(), Cipher.MODE_DECRYPT);
but it did not help :(.
Yes, I searched the forum first. I am not sure if the problem is located in my decrypt-method or if my offcard-applet is wrong (the ct_data..... above).
I searched more and found out that it could be a wrong set Le-field...
Message was edited by:
susikaufmann
# 11
I was wrong before. The Le field is not correct. Data available for T=0 it would be '61xx'.Find out how you can set the Le field with the CT_Data method.
# 12
This is how I create my command:
byte[] decrypt = {
0x00,
0x70,
0x00,
0x00,
(byte)0x80
};
...
byte[] p = cipher.doFinal(s.getBytes());
byte[] temp = appendByteArray(decrypt, p); // appendbytearray adds the second array to the first one
byte[] len = {(byte)0x06};
decryptCommand = appendByteArray(temp, len);
...
byte[] rsp3 = new byte[256];
rc = reader.CT_Data((char) 1, (byte)0, (byte)2, decryptCommand.length, (byte[])decryptCommand, (char) lr, rsp3);
# 13
The problem is that your Le field differs from your outbytes.
Try the following: short le = apdu.setOutgoing();
returns the length of the Le field. Optionally you can use le inapdu.setOutgoingLength(le);
Then callapdu.sendBytesLong(apduBuffer, (short)ISO7816.OFFSET_CDATA, le);
If this won't help, set in your command the Le field to '00'.
# 14
Mmh...tried all but without success :(. I have seen in another method of mine:if the le-value is to big, then I get the same error.So I tried now several values (0x00, 0x01.....0x06). I guess I will try some more.
# 15
Sorry for asking again, but I cannot fix my problem. Am I looking at the wrong point? I tried several values with the variable "le".
private void decrypt(APDU apdu)
{
short byteRead = (short)(apdu.setIncomingAndReceive());
cipher.init((RSAPrivateCrtKey)keypair.getPrivate(), Cipher.MODE_DECRYPT);
short outbytes;
byte[] apduBuffer = apdu.getBuffer();
outbytes = cipher.doFinal(apduBuffer,(short)ISO7816.OFFSET_CDATA, byteRead, apduBuffer, (short)ISO7816.OFFSET_CDATA);
short le = apdu.setOutgoing();
// this is the variable I tried several values with
le = 0x00;
apdu.setOutgoingLength(le);
apdu.sendBytesLong(apduBuffer, (short)ISO7816.OFFSET_CDATA, (short)outbytes);
}
# 16
You need to set the Le field in the command APDU --> card send me no data or as much as you want. There is no Le field in the response APDU.
# 17
Ok, but when I set the command APDUs Le field to 0x00, the card should send all available response data, shouldn't it?
byte[] decrypt = {
0x00, // CLA
0x70, // INS
0x00,// P1
0x00,// P2
(byte)0x80// Lc
};
The Lc is 0x80, because the encrypted data has a length of 128.
So I append now the encrypted data bytes. After that I append the Le, e.g. 0x00. But I still get "6c 01". :-(
# 18
Ok, i have got it. IT seems, that 0x70 is not allowed as INS byte...
# 19
Sorry, I overlooked that you used INS=0x70 = GlobalPlatform MANAGE CHANNEL command (9.7, Table 9-43). This cannot work. The INS is not passed to the Applet but handled by the OPEN (CardManager).