如何让智能卡Applet接收所有SELECT APDU命令并始终处于选中状态?
让Java Card Applet接收所有SELECT APDU命令的方法
要让你的Applet始终处于选中状态并接收所有APDU(包括SELECT命令),得从卡的配置和Applet代码两方面入手,下面是具体的思路和实现步骤:
1. 先把Applet设为默认选中
首先,你需要在卡个性化阶段,把你的Applet设置为默认选中Applet。这一步通常用GlobalPlatform工具来完成,比如执行类似这样的命令:
gp -d -default YOUR_APPLET_AID
这样卡上电后会自动选中你的Applet,不需要额外发送SELECT命令来激活它。但这只是第一步,默认选中还不足以让它拦截所有SELECT命令——因为通常卡管理器(安全域)会优先处理选择其他AID的SELECT命令。
2. 在Applet中拦截并处理所有SELECT命令
接下来要修改你的Applet代码,重写process()方法,拦截所有INS为0xA4的APDU(也就是SELECT命令),自己处理这些请求,不让卡管理器插手。
示例代码如下:
import javacard.framework.*; public class AlwaysSelectedApplet extends Applet { private AlwaysSelectedApplet() {} public static void install(byte[] bArray, short bOffset, byte bLength) { new AlwaysSelectedApplet().register(); } @Override public void process(APDU apdu) { byte[] buffer = apdu.getBuffer(); // 检测是否是SELECT命令(INS = 0xA4) if ((buffer[ISO7816.OFFSET_INS] == (byte)0xA4)) { // 这里可以自定义处理逻辑,比如返回成功状态字9000 // 如果需要返回数据,也可以在这里设置输出 apdu.setOutgoingAndSend((short)0, (short)0); return; } // 处理其他非SELECT命令的逻辑 // ... } }
当你的Applet处理了SELECT命令并返回成功状态(比如9000),卡就不会再把这个命令转发给安全域,也不会触发Applet切换——这样你的Applet就能始终保持选中状态,接收所有APDU。
3. 注意卡的兼容性问题
要提醒一下,不同厂商的Java Card可能有不同的行为限制:
- 有些卡可能强制让安全域优先处理SELECT命令,这时候你可能需要联系卡厂商获取特殊权限,或者把你的Applet注册为安全域(安全域可以处理所有管理类命令,包括SELECT,但开发安全域需要额外的权限和厂商支持)。
- 如果你的Applet需要区分“选择AID”和“选择文件”类型的SELECT命令,可以通过P1/P2参数来判断(比如选择AID通常是
P1=04, P2=00),再做针对性处理。
内容的提问来源于stack exchange,提问作者Ebrahim Ghasemi




