if i want to encrypt a message that i send to Java Card applet like DES

What are the steps that i have to do ? is there something missing?

//set the private key

privatebyte[] KeyData ={0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,

0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,0x39, 0x40};

deskey = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_DESELECT,

KeyBuilder.LENGTH_DES,false);

deskey.setKey(KeyData, (short)0);

//InData and OutData are two byte variables for the input message and the //Output message

Cipher cipher;

cipher = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD ,false);

cipher.init(deskey, Cipher.MODE_ENCRYPT);

cipher.doFinal((byte[])InData,(short) 0 , (short) InData.length,(byte[]) OutData,(short) 0);

is that correct? or needs something else?

if i set fixed size for Outdata byte i have to do Padding since i choose (ALG_DES_CBC_NOPAD) method? in order to send the cipher back to host application Thru APDU command?

How big can the cipher become with the key i used if InData are byte[10]

Thanks in advance

[1537 byte] By [Kanastasiosa] at [2007-11-27 5:20:59]
# 1
Looks good. Do you get any errors? Paste the APDU trace.
lexdabeara at 2007-7-12 11:45:43 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 2

Well that what i get no data back maybe they don't fit in the byte array variable i try to send as response i think i should check for padding

The APDU command is this:

byte [] InData = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

apdu.setOutgoingLength((byte) (30) );

apdu.sendBytesLong( InData, (short)0, (byte)30);

RESULTS:

CLA: b0, INS: 40, P1: 00, P2: 00, Lc: 00, Le: 00, SW1: 6f, SW2: 00

Kanastasiosa at 2007-7-12 11:45:43 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 3
It seems like the APDU is not processed by your applet. How does your process method look like?
lexdabeara at 2007-7-12 11:45:43 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 4

as u Can see i call "readrec"

ignore comments

//Here is the Proceess

public void process(APDU apdu) {

byte[] buffer = apdu.getBuffer();

if ((buffer[ISO7816.OFFSET_CLA]==0) && (buffer[ISO7816.OFFSET_INS])== (byte) 0xa4) return;

if (buffer[ISO7816.OFFSET_CLA]!=MedBooklet_CLA)

ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

switch (buffer[ISO7816.OFFSET_INS]) {

case ADDRECENTRY: addrec(apdu);

return;

case READRECENTRY: readrec(apdu);

return;

case VERIFY: verify(apdu);

return;

}

}

public void readrec(APDU apdu) {

byte[] buffer = apdu.getBuffer();

short le = apdu.setOutgoing();

//the encryption starts here

deskey = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_DESELECT,

KeyBuilder.LENGTH_DES, false);

deskey.setKey(KeyData, (short)0);

Cipher cipher;

cipher = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD ,false);

cipher.init(deskey, Cipher.MODE_ENCRYPT);

cipher.doFinal((byte[])InData,(short) 0 , (short) InData.length,(byte[]) OutData,(short) 0);

//TESTING TESTING

//if (OutData.length==8){

//apdu.setOutgoingLength((byte)8);

//apdu.sendBytesLong((byte[])OutData, (short)0, (short)8);

apdu.setOutgoingLength((byte) (30) );

apdu.sendBytesLong( Data, (short)0, (byte)30);

//}else ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

}

Kanastasiosa at 2007-7-12 11:45:43 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 5

Good practice is to have a default: in a switch/case branching. Add default and throw an exception != 'No specific diagnosis error' (0x6F00).

Second thing would be to try/catch the readrec method and include all JC exceptions in the catch --> this way you can tell what goes wrong (e.g. ARRAY_INDEX_OUT_OF_BOUNDS --> return (short)B000 or CryptoException.NO_SUCH_ALGORITHM --> return (short)B001 ..).

lexdabeara at 2007-7-12 11:45:43 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 6

I wouldn't do the following code snippet on every readrec.

Cipher cipher;

cipher = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD ,false);

I would move that to the constructor or init. If you have a use case where the ALG_DES_* might need to be dynamic, then I would leave the getInstance() there. But if it's the same all the time, no need to call that everytime readrec() is processed.

my two cents.

Joseph.Smitha at 2007-7-12 11:45:43 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 7

I tried too many corrections and i still get unknown error

i tried this code this time

package gr.teiath.netlab.applets;

import javacard.framework.*;

import javacard.security.DESKey;

import javacard.security.KeyBuilder;

import javacardx.crypto.Cipher;

public class MedBooklet extends Applet {

final static byte MedBooklet_CLA = (byte) 0xB0;

// PIN relatives

final static byte PIN_TRY_LIMIT = (byte) 0x03;

final static byte MAX_PIN_SIZE = (byte) 0x04;

OwnerPIN pin;

//DES

byte keyArray[] = {(byte)0x09,(byte)0x0e,(byte)0x0d,(byte)0x0c,(byte)0x0b,(byte)0x0a,(byte)0x09,(byte)0x08,

(byte)0x09,(byte)0x0e,(byte)0x0d,(byte)0x0c,(byte)0x0b,(byte)0x0a,(byte)0x09,(byte)0x08,

(byte)0x09,(byte)0x0e,(byte)0x0d,(byte)0x0c,(byte)0x0b,(byte)0x0a,(byte)0x09,(byte)0x08};

private byte[] outBuff;

private short Lc;

// allocate key object

DESKey desKey;

Cipher cipher;

// Return codes

final static short SW_VERIFICATION_FAILED = 0x6300;

// INS commands

final static byte VERIFY = (byte)0x20;

final static byte ADDRECENTRY = (byte)0x30;

final static byte READRECENTRY = (byte)0x40;

//private RecipeFile recipeFile;

//private ReferFile referFile;

private MedBooklet(byte[] bArray, short bOffset, byte bLength) {

pin = new OwnerPIN(PIN_TRY_LIMIT,MAX_PIN_SIZE);

pin.update(bArray, bOffset, bLength);

desKey = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES,KeyBuilder.LENGTH_DES,false);

// set key value

desKey.setKey(keyArray,(short)0x00);

//recipeFile = new RecipeFile();

//referFile = new ReferFile();

register();

}

public static void install(byte[] bArray, short bOffset, byte bLength) {

new MedBooklet(bArray,bOffset,bLength);

}

public boolean select() {

if(pin.getTriesRemaining()==0) return false;

return true;

}

public void deselect() {

pin.reset();

}

public void process(APDU apdu) {

byte[] buffer = apdu.getBuffer();

if ((buffer[ISO7816.OFFSET_CLA]==0) && (buffer[ISO7816.OFFSET_INS])== (byte) 0xa4) return;

if (buffer[ISO7816.OFFSET_CLA]!=MedBooklet_CLA)

ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

switch (buffer[ISO7816.OFFSET_INS]) {

case ADDRECENTRY: addrec(apdu);

return;

case READRECENTRY: readrec(apdu);

return;

case VERIFY: verify(apdu);

return;

}

}

public void addrec(APDU apdu){

//byte[] buffer = apdu.getBuffer();

//byte byteRead = (byte) (apdu.setIncomingAndReceive());

//if (byteRead==0x1f)

//recipeFile.newRecord(buffer, ISO7816.OFFSET_CDATA, (short) byteRead);

// create cipher instance

cipher = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD,false);

byte[] buf = apdu.getBuffer();

Lc = (short) (buf[ISO7816.OFFSET_LC] & 0x00FF);

//array storing output buffer

outBuff = new byte[Lc];

// initialize cipher

cipher.init(desKey,Cipher.MODE_ENCRYPT);

Lc = cipher.doFinal(buf,(short)ISO7816.OFFSET_CDATA,Lc,outBuff,(short)0x00);

// set output to be returned with same size of the input

apdu.setOutgoing();

apdu.setOutgoingLength(Lc);

apdu.sendBytesLong(outBuff,(short)0x00,Lc);

}

public void readrec(APDU apdu) {

byte[] buffer = apdu.getBuffer();

short le = apdu.setOutgoing();

apdu.setOutgoingLength( (short) (35) );

// echo header

//apdu.sendBytes( (short)0, (short) 5);

// echo data

// apdu.sendBytesLong( recipeFile.getRecord() , (short) 0, (short) 35 );

}

private void verify(APDU apdu) {

byte[] buffer = apdu.getBuffer();

byte byteRead = (byte) (apdu.setIncomingAndReceive());

if (pin.check(buffer, ISO7816.OFFSET_CDATA, byteRead)== false)

ISOException.throwIt(SW_VERIFICATION_FAILED);

}

}

I have another Problem When in constructor i try to

cipher = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD,false);

I cant veriry the PIN so i always get exit command are there conflicts when are in the same constructor between

pin.update(bArray, bOffset, bLength);

VS

cipher = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD,false);

VS

register();

Are there Limitations about "Cref" do i have to send the data to be encrypted no more than byte of 8 hex ?

Kanastasiosa at 2007-7-12 11:45:43 > top of Java-index,Java Mobility Forums,Consumer and Commerce...