(买家当心:似乎这种方式根本行不通——见评论)
(在 GlobalPlatform 卡规范 2.2.1 的上下文中)
您必须遵守图 5-2 中描述的应用程序生命周期状态规则(此处适用标记为“5”的箭头)。
正确的方法应该是:
GPSystem.setCardContentState((byte)(GPSystem.getCardContentState() | GPSystem.APPLICATION_LOCKED));
或者
GPSystem.getRegistryEntry(JCSystem.getAID()).setState((byte)(GPSystem.getCardContentState() | GPSystem.APPLICATION_LOCKED))
应用程序的0x80
生命周期状态无效。请参见表 11-4(至少必须设置b1
和位,可能也设置位)。b2
b3
编辑>
(我承认写这个答案完全是基于对 OPEN 保持实体被锁定的原始状态这一事实的记忆)
我对此很好奇,所以我使用以下小程序(摘录)做了一些测试:
public void process(APDU apdu) {
byte[] buffer = apdu.getBuffer();
if(selectingApplet()) {
return;
}
short claIns = Util.getShort(buffer, ISO7816.OFFSET_CLA);
switch(claIns) {
case (short) 0x8007:
buffer[0]=GPSystem.getCardContentState();
if(buffer[0]==buffer[ISO7816.OFFSET_P1]) {
if(GPSystem.setCardContentState(buffer[ISO7816.OFFSET_P2])) {
buffer[1]=0x01;
} else {
buffer[1]=0x00;
}
} else {
buffer[1]=(byte)0xFF;
}
buffer[2]=GPSystem.getCardContentState();
apdu.setOutgoingAndSend((short)0, (short)3);
return;
default: {
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
return;
}
}
}
以及以下 APDU:
8007070F03 // To test transition into Application Specific State
80070F8F03 // To test my theory
80070F8003 // To test the GPSystem.APPLICATION_LOCKED constant directly
我的一组卡片(Gemalto、Morpho、JCOP - 不幸的是它们都是 GP 2.1.1)的结果符合 Michael Roland 的出色答案和 GP 规范 - 应用程序尝试阻止自身被拒绝。
收到所有 GP 2.1.1 卡的响应 APDU:
8007070F03 -> 07010F9000 // Succeeded in transition from `07` to `0F`
80070F8F03 -> 0F000F9000 // Failed transition from `0F` to `8F`
80070F8003 -> 0F000F9000 // Failed transition from `0F` to `80`
请注意:此工具在解析卡识别数据时对于确定实施的 GP 版本非常有用。