I want to write my applet in a way that its APDU commands and status words wasn't be clear in the transmission channel between my card and my reader. I mean I don't want to send APDU commands and responses to be plain text for third parties.
I think I have two option :
SELECT
APDU command and the SD of card recognize it as a SELECT
command wrongly. is that right?Its Diagram :
Its Diagram :
Is there any other way?
It seems that the first solution is not good enough, because :
Am I right?
Now, let assume that I want to be sure that my applet works only with APDU commands that transmitted using secure channel . I think I have two option again :
Put the card in SECURED
state. As the user can't communicate with the card with plain text APDU commands in this state (right?) therefore he must send the commands to my applet using secure channel. right? if it is not correct, is there any way to force the SD to work with Secure Channel only?
Keep the card in any life cycle that it is (for example OP_READY), But instead, on reception of any APDU command, check the CLA section to see if it is a secure transmitted or not! (Is it possible? Is there any difference between CLA
part of APDU commands that come from secure channel and the other ones? Am I right?)
Is there any other way?
And finally the main question :
How can I use SD to have a secure communication with my applet? As I thought I must use GlobalPlatform classes(Am I?), I took a look at its API-s. I found a method named getSecureChannel
in a package named org.globalplatform.GPSystem
. Am I in a right way? Am I must use this method?
I know that this may be too long to answer, but I'm sure that it clarify a lot of questions not only for me, but also for other future viewers.
I appreciate any body shed any light in this issue for me.
And a sample applet is more appreciable.
Don't worry for secure channel communication via applet. It's very simple if you use Global Platform APIs in your applet.
You don't need to think about lot's of questions, just try to write an secure channel applet and it will process your applet as per defined security level in the command data.
Refer GP secure channel APIs: http://www.win.tue.nl/pinpasjc/docs/apis/gp22/
And you should keep the card in SECURED state.
And this is the sample applet for secure channel scp02:
package secureChannel;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import org.globalplatform.GPSystem;
import org.globalplatform.SecureChannel;
public class Scp02 extends Applet
{
final static byte INIT_UPDATE = (byte) 0x50;
final static byte EXT_AUTHENTICATE = (byte) 0x82;
final static byte STORE_DATA = (byte) 0xE2;
public static void install(byte[] bArray, short sOffset, byte bLength)
{
new Scp02().register(bArray, sOffset, bLength);
}
public void process(APDU apdu) throws ISOException
{
SecureChannel sc = GPSystem.getSecureChannel();
byte[] buffer = apdu.getBuffer();
short inlength = 0;
switch (ISO7816.OFFSET_INS)
{
case INIT_UPDATE:
case EXT_AUTHENTICATE:
inlength = apdu.setIncomingAndReceive();
sc.processSecurity(apdu);
break;
case STORE_DATA:
//Receive command data
inlength = apdu.setIncomingAndReceive();
inlength = sc.unwrap(buffer, (short) 0, inlength);
apdu.setOutgoingAndSend((short)0, inlength);
//Process data
break;
}
}
}
I'll answer in order:
For the sake of Google search, the code from Anurag Bajpai doesn't work without a slight modification since, as stated in GP secure channel APIs, the applet should output eventual response data:
If response data is present, this data will be placed in the APDU buffer at offset ISO7816.OFFSET_CDATA. The return value indicates the length and the applet is responsible for outputting this data if necessary.
Hence, the corrected code is:
package secureChannel;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import org.globalplatform.GPSystem;
import org.globalplatform.SecureChannel;
public class Scp02 extends Applet
{
final static byte INIT_UPDATE = (byte) 0x50;
final static byte EXT_AUTHENTICATE = (byte) 0x82;
final static byte STORE_DATA = (byte) 0xE2;
public static void install(byte[] bArray, short sOffset, byte bLength)
{
new Scp02().register(bArray, sOffset, bLength);
}
public void process(APDU apdu) throws ISOException
{
SecureChannel sc = GPSystem.getSecureChannel();
byte[] buffer = apdu.getBuffer();
short inlength = 0;
switch (ISO7816.OFFSET_INS)
{
case INIT_UPDATE:
case EXT_AUTHENTICATE:
inlength = apdu.setIncomingAndReceive();
short respLen = sc.processSecurity(apdu);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, respLen);
break;
case STORE_DATA:
//Receive command data
inlength = apdu.setIncomingAndReceive();
inlength = sc.unwrap(buffer, (short) 0, inlength);
apdu.setOutgoingAndSend((short)0, inlength);
//Process data
break;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With