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

[990 byte] By [susikaufmanna] at [2007-11-27 7:10:48]
# 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.
Joseph.Smitha at 2007-7-12 19:02:22 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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

susikaufmanna at 2007-7-12 19:02:22 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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?

lexdabeara at 2007-7-12 19:02:22 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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
susikaufmanna at 2007-7-12 19:02:22 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 5
If you're sure that your card uses T=1, then the only possibility is that the '6C01' is generated by your applet.
lexdabeara at 2007-7-12 19:02:22 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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
susikaufmanna at 2007-7-12 19:02:22 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 7
Can you post the applet source code? It might be the applet is returning '6C01'.
lexdabeara at 2007-7-12 19:02:22 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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.

susikaufmanna at 2007-7-12 19:02:22 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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

Joseph.Smitha at 2007-7-12 19:02:22 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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

susikaufmanna at 2007-7-12 19:02:23 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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.
lexdabeara at 2007-7-12 19:02:23 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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);

susikaufmanna at 2007-7-12 19:02:23 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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'.

lexdabeara at 2007-7-12 19:02:23 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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.
susikaufmanna at 2007-7-12 19:02:23 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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);

}

susikaufmanna at 2007-7-21 22:14:00 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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.
lexdabeara at 2007-7-21 22:14:00 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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". :-(

susikaufmanna at 2007-7-21 22:14:00 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 18
Ok, i have got it. IT seems, that 0x70 is not allowed as INS byte...
susikaufmanna at 2007-7-21 22:14:00 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 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).
lexdabeara at 2007-7-21 22:14:00 > top of Java-index,Java Mobility Forums,Consumer and Commerce...