问题
I would like to know if there is a way of changing the historical bytes automatically as you power your smartcard, in order to have different response if on contact or contactless.
In Javacard you can use setATRHistBytes
, and also call it depending on the access interface. But the changes would be reflected on next power up of the card. I want to set them intermediately.
TA
回答1:
Actually the contact-less interface has no attribute named ATR. Because ATR is for contact interface only. The counterpart on the contactless interface is named ATS.
As you said in your question, you can change ATR using setATRHistBytes
of Global Platform APIs. Here is the description of this method:
setATRHistBytes
public static boolean setATRHistBytes(byte[] baBuffer, short sOffset, bytebLength)
For contact cards according to ISO/IEC 7816-4 and Type A contactless cards according to ISO/IEC 14443-3, this method sets the historical bytes. The sequence of bytes will be visible on a subsequent power-up or reset.
Notes:
• The OPEN locates the entry of the current applet context in the GlobalPlatform Registry and verifies that the Application has the Card Reset privilege for the current card I/O interface;
• The OPEN is responsible for synchronizing the length of historical bytes in Format Character T0 of the ATR.
Parameters:
baBuffer - the source byte array containing the historical bytes. Must be a global array.
sOffset - offset of the historical bytes within the source byte array.
bLength - the number of historical bytes.
Returns:
true if historical bytes set, false if the Application does not have the required privilege.
As you see in the Notes section, your applet must has Card Reset privilege. Without this privilege, you can't change the historical bytes. Use the below command in GlobalPlatformPro tool to install your applet with Card Reset privilege:
CommandLine> gp.exe -install <PathToYourApplet\apple.cap> --default
I already wrote a program to change ATR of my java card. You can try it. (Anyway, I'm not sure about it)
package testATR;
import org.globalplatform.GPSystem;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
public class HistoricalBytesChanger extends Applet {
public static byte[] state = { (byte) 0, (byte) 0 };
public static byte[] HistByteArray = { (byte) 0x01, (byte) 0x02,
(byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
(byte) 0x08, (byte) 0x09, (byte) 0x0a };
public static void install(byte[] bArray, short bOffset, byte bLength) {
new HistoricalBytesChanger().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buf = apdu.getBuffer();
switch (buf[ISO7816.OFFSET_INS]) {
case (byte) 0x00:
GPSystem.setATRHistBytes(HistByteArray, (short) 0, (byte) 10);
HistByteArray[0] = (byte) (HistByteArray[0] + 1);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
}
I wonder if you can change ATS or not. Anyway if you want to have different ATR and ATS (Normally they are different by default!), you just need to change ATR.
Take a look at this Q&A and the comments
来源:https://stackoverflow.com/questions/31385215/smartcard-with-different-historical-bytes-depending-on-interface