Java Card 客户端-服务器共享接口返回 6F00

Posted

技术标签:

【中文标题】Java Card 客户端-服务器共享接口返回 6F00【英文标题】:Java Card client-server Shareable interface returns 6F00 【发布时间】:2019-01-06 14:04:54 【问题描述】:

我尝试使用可共享接口的 Eclipse 3.7 SDK 在 java card 2.2.2 中创建一个简单的客户端和服务器小程序。当方法JCSystem.getAppletShareableInterfaceObject 被调用时,它会抛出一个异常,因此返回SW 设置为6F00。

这是客户端应用代码 (Test_Client.java):

    package client;

import server.Test_ServerInf;
import javacard.framework.AID;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;

public class Test_Client extends Applet 

    protected static final byte INS1 = (byte)0xE2;
    protected static final byte INS2 = (byte)0x21;

    byte[] ServerAIDbyte=(byte)0x20,(byte)0x21,(byte)0x22,(byte)0x23,(byte)0x24,(byte)0x25,(byte)0x26,(byte)0x27,(byte)0x01;
    AID ServerAID;

    private Test_Client() 
    

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException 
        new Test_Client().register();
    

    public void process(APDU apdu) throws ISOException 
        // TODO Auto-generated method stub
        byte[] apduBuffer = apdu.getBuffer();

        byte Ins=apduBuffer[ISO7816.OFFSET_INS];
        short byteread = apdu.setIncomingAndReceive();

        if (selectingApplet())
            return;

        switch (Ins)
        case INS1:
            Ins1_Handler(apdu);
            return;
        case INS2:
            Ins2_Handler(apdu,apduBuffer);
            return;
        default:
            ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
        
    
    private void Ins1_Handler(APDU apdu)
        Test_ServerInf sio = null;
        ServerAID=JCSystem.lookupAID(ServerAIDbyte,(short) 0,(byte) ServerAIDbyte.length);
        if(ServerAID==null)
            ISOException.throwIt( (short) 0x6A82);
        ////server request
        try
        sio=(Test_ServerInf)(JCSystem.getAppletShareableInterfaceObject(ServerAID, (byte) 0));
        
        catch(SecurityException e)
       
           ISOException.throwIt((short)0x12);
       
       catch(Exception e)
       
           ISOException.throwIt((short)0x10);
       
        if(sio==null)
            ISOException.throwIt((short)0x6A00);

    

    private void Ins2_Handler(APDU apdu,byte[] apduBuffer)
            Test_ServerInf sio = null;
           ////connect to server  
          ServerAID=JCSystem.lookupAID(ServerAIDbyte,(short) 0,(byte) ServerAIDbyte.length);
           if(ServerAID==null)
                ISOException.throwIt( (short) 0x6A82);
           ////server request
           try
               sio=(Test_ServerInf)(JCSystem.getAppletShareableInterfaceObject(ServerAID, (byte) 0));
           
           catch(SecurityException e)
           
               ISOException.throwIt((short)0x12);
           
           catch(Exception e)
           
               ISOException.throwIt((short)0x10);
           
           if(sio==null)
                ISOException.throwIt((short)0x6A00); 
    



这是服务器小程序代码 (Test_Server.java):

  package server;

import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import server.Test_ServerInf;
import javacard.framework.Shareable;
import javacard.framework.AID;

public class Test_Server extends Applet implements Test_ServerInf


    private Test_Server() 
    

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException 
        new Test_Server().register();
    

    public void process(APDU apdu) throws ISOException 
        // TODO Auto-generated method stub

    

    public Shareable getShareableInterfaceObject(AID clientAID, byte parameter) 
        return this;
    

    public short method1()
        return (short)0x01;
    
    public short method2()
        return (short)0x02;
    


以及可共享的接口文件(Test_ServerInf.java):

package server;

import javacard.framework.Shareable;

public interface Test_ServerInf extends Shareable 

    public short method1();
    public short method2();


【问题讨论】:

那么catch 捕获的异常是Ins2_Handler 吗?如果是这样,您是否尝试打印出原因?请注意,我们在线“调试”特别困难,我们甚至不知道您如何以及是否已实例化服务器等。 @MaartenBodewes 是的,这是一个例外,但它是RuntimeException 而不是CardRuntimeException,因此它不包含除equals() 之外的任何方法。我已经实例化了服务器和客户端。 JCSystem.getAppletShareableInterfaceObject 抛出的唯一异常是 SecurityException 您是否尝试移除演员表?鉴于该位置的官方 JC API,我只能看到另一个可能的异常。 @MaartenBodewes 是的,它再次抛出该异常,但是删除强制转换会导致无法使用接口的内部方法。 烦恼。可以在Exception 之前分别捕获SecurityException 吗?它也没有原因码,所以我们至少知道抛出了哪个异常(是的,我知道,它是唯一应该被抛出的异常,但是......)。跨度> 【参考方案1】:

您正在尝试将可共享接口对象的引用存储在客户端小程序类的成员字段中:

sio = (Test_ServerInf)(JCSystem.getAppletShareableInterfaceObject(ServerAID, (byte) 0));

其中sio 被定义为applet 类实例的私有成员:

public class Test_Client extends Applet 
    private Test_ServerInf sio;

这将导致SecurityException,因为可共享接口对象由服务器小程序拥有(即由不同的上下文拥有)。不允许将其他上下文拥有的对象存储在实例字段中。

请参阅访问类实例对象字段(第 6.2.8.3 节)运行时环境规范,Java Card 平台,版本 2.2.2

字节码:getfieldputfield

[...] 如果对象由当前活动上下文中的小程序拥有,则允许访问。 否则,访问将被拒绝。

【讨论】:

D'oh,我已经说过我在答案下方的 cmets 中生锈了。幸运的是你没有:) 也有道理,永久存储引用是不允许的。如果另一个小程序被删除一个,你会怎么做,它会和 GC 玩得很开心。 考虑到您的注释,我已经更新了上面的源代码,但它会像以前的代码一样抛出异常。 @1chenar 我没主意了 :-( @1chenar 你没有让你的服务器小程序成为默认选择的小程序,对吧?而且您正在基本逻辑通道上进行测试,对吗? @MichaelRoland 是的。【参考方案2】:

我找到了这个错误的根源。我曾经使用内部开发的应用程序而不是 GPSShell 来加载和安装小程序。当我尝试使用 GPSShell 加载和安装小程序时,问题解决了,一切正常。我不知道该应用程序如何破坏加载的包,但它可以正常工作(经过 2 周的调试)。

【讨论】:

以上是关于Java Card 客户端-服务器共享接口返回 6F00的主要内容,如果未能解决你的问题,请参考以下文章

java 怎么写一个接口 让他返回服务器的动态IP地址和端口?

聚合数据实名认证接口-java方法

6.2Java多线程Callable接口

java~接口的共享实体使用Map后更灵活

PCI-E 2x8 Riser Card 是啥意思

RPC调用基础及Java学习笔记