You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaCard共享接口方法无法访问传入数据的问题排查

JavaCard跨Applet调用Shareable接口异常问题

问题背景

作为JavaCard小程序开发新手,尝试通过Shareable接口实现跨Applet方法调用,但遇到异常:发送APDU指令00 11 00 00时,返回6F00 (SW_UNKNOWN),预期是SW_CONDITIONS_NOT_SATISFIED;但如果不在checkNumber方法中操作传入的数组,能正常返回SW_WRONG_DATA。

代码实现

共享接口定义(Configurations.java)

public interface Configuration extends Shareable {
    public void checkNumber(byte[] number);
}

提供共享接口的SourceApplet

// sourceapplet.java
public void checkNumber(byte[] number) {
    short numberLength = (short)number.length;
    if (numberLength < 6) {
        ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
    }
    ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}

调用接口的TargetApplet

// targetapplet.java
public final class TargetApplet extends Applet implements MultiSelectable {
    private static final byte INS_TEST_CHECK_NUMBER = (byte) 0x11;
    private AID checkNumberAppletAID;
    private TargetApplet() {
        // 初始化checkNumberApplet的AID
        byte[] aidBytes = {(byte) 0xB2, 0x86, 0x00, 0x00, 0x00, 0x01};
        checkNumberAppletAID = JCSystem.lookupAID(aidBytes, (short)0, (byte) aidBytes.length);
        
        if (checkNumberAppletAID == null) {
            ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND); // 未找到小程序
        }
    }

    public void process(APDU apdu) {
        final byte[] buffer = apdu.getBuffer();
        final byte ins = buffer[ISO7816.OFFSET_INS];
        switch (ins) {
        case INS_TEST_CHECK_NUMBER:
            processCheckNumber(apdu);
            break;
        default:
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    }

    private void processCheckNumber(APDU apdu) {
        Configuration config = (Configuration) JCSystem.getAppletShareableInterfaceObject(checkNumberAppletAID, (byte) 0x00);
        if (config == null) {
            ISOException.throwIt(ISO7816.SW_APPLET_SELECT_FAILED);
        }
        
        byte[] number = new byte[]{1,2,3,4};
        // byte[] number = new byte[] {(byte) '1', (byte) '2', (byte) '3', (byte) '4'};
        config.checkNumber(number);
    }
}

尝试的解决方案及结果

更新1:更换内存类型

  • 使用瞬态内存:在TargetApplet中用JCSystem.makeTransientByteArray创建数组,结果仍异常。
  • 使用持久化内存:在TargetApplet中用new byte[4]创建数组,结果仍异常。

更新2:添加异常捕获

在SourceApplet的checkNumber方法中添加try-catch:

public void checkNumber(byte[] number) {
    try {           
        short numberLength = (short)number.length;
        if (numberLength < 6) {
            ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
        }
    } catch (ISOException e) {
        ISOException.throwIt(e.getReason());
    } catch (SecurityException e) {
        ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
    }
}

现在返回6982 SW_SECURITY_STATUS_NOT_SATISFIED。

疑问

  • 问题根源是什么?如何解决?
  • TargetApplet中传入的number数组是否存在问题?

解答

问题原因

JavaCard的安全沙箱机制限制了跨Applet访问内存:当SourceApplet尝试访问TargetApplet创建的数组的length属性时,会触发SecurityException。不同Applet拥有独立的内存空间,默认不允许直接访问对方对象的内部属性(包括数组长度)。未捕获该异常时,会返回通用错误6F00;捕获后则返回自定义的6982。

解决方案

修改共享接口设计,由调用方(TargetApplet)主动传入数组长度,避免跨Applet访问对象内部属性:

  1. 更新共享接口
// Configurations.java
public interface Configuration extends Shareable {
    public void checkNumber(byte[] number, short length);
}
  1. 修改SourceApplet实现
public void checkNumber(byte[] number, short length) {
    if (length < 6) {
        ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
    }
    ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
  1. 修改TargetApplet调用逻辑
private void processCheckNumber(APDU apdu) {
    Configuration config = (Configuration) JCSystem.getAppletShareableInterfaceObject(checkNumberAppletAID, (byte) 0x00);
    if (config == null) {
        ISOException.throwIt(ISO7816.SW_APPLET_SELECT_FAILED);
    }
    
    byte[] number = new byte[]{1,2,3,4};
    config.checkNumber(number, (short)number.length);
}

原理说明

JavaCard的Shareable接口仅允许跨Applet调用方法,但方法参数中对象的内部属性访问受沙箱限制。通过主动传入数组长度,避开了跨Applet访问对象内部属性的操作,符合安全规范,同时能实现预期的业务逻辑。


内容的提问来源于stack exchange,提问作者Preeti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 10:29:55