【问题标题】:Java Card to send data without get data APDUJava Card发送数据而不获取数据APDU
【发布时间】:2015-07-21 11:52:38
【问题描述】:

我是这个领域的新手,如果我的问题很幼稚,请原谅我。

我想发行一个带有自动选择小程序的 Java 卡,几乎所有的 APDU 都将在这个小程序中得到处理。我需要这个小程序以不使用 Java 卡标准中的常用格式将数据发送到 CAD(即不发送 0x61 0xbytesToRead 并等待 0x00 0xc0)。
例如,我想发送0x23 字节来回复0xA0A40000027F20,这几乎是一个SELECT 命令,但第一个字节错误!

那么有可能做到这一点吗?如果可能,请告诉我怎么做。

谢谢。

【问题讨论】:

    标签: applet javacard


    【解决方案1】:

    是的,这是可能的。要实现目标,您需要执行以下两个步骤:

    1. 您必须将您的小程序默认选中。
    2. 您必须在收到此命令和/或收到 SELECT APDU 命令时返回一些数据。

    第一步,如回答here

    这取决于卡 - 并非所有卡似乎都支持在安装后将小程序设为默认值。但是您可以使用具有 --make-default 选项的 Java 开源 GlobalPlatform 工具:

    java -jar gp.jar --make-default A000100201100001
    

    IIRC JCOP 是实际支持它的卡之一。

    第二步,正如here 的回答:

    我猜你正在做“如果选择Applet()然后返回”的“好习惯”?您需要处理传入的 APDU 而不是简单的返回。 可以正常方式返回数据选择,但注意选择成功时返回0x9000。

    它必须看起来像这样:

    public void process(APDU apdu)
        { 
           byte[] buf = apdu.getBuffer();
           if (selectingApplet())
              { 
              //send the data in buffer return;
              }
        } 
    

    更新:

    在此答案下方回答您的评论:

    我写了下面的程序:

    package test;
    
    import javacard.framework.APDU;
    import javacard.framework.ISO7816;
    import javacard.framework.Applet;
    import javacard.framework.ISOException;
    import javacard.framework.Util;
    
    public class Test extends Applet {
    
        public static final byte[] res = { (byte) 0x00, (byte) 0x00, (byte) 0x3B,
                (byte) 0xAD, (byte) 0x3F, (byte) 0x00, (byte) 0x01, (byte) 0x00,
                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x16,
                (byte) 0xB3, (byte) 0x03, (byte) 0x06, (byte) 0x04, (byte) 0x00,
                (byte) 0x83, (byte) 0x8A, (byte) 0x83, (byte) 0x8A, (byte) 0x00,
                (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3B, (byte) 0xAD,
                (byte) 0x00, (byte) 0x00, (byte) 0x3B, (byte) 0xAD, (byte) 0x2F,
                (byte) 0x06, (byte) 0x02 };
    
        public static void install(byte[] bArray, short bOffset, byte bLength) {
            new test.Test()
                    .register(bArray, (short) (bOffset + 1), bArray[bOffset]);
        }
    
        public void process(APDU apdu) {
            if (selectingApplet()) {
                return;
            }
    
            byte[] buf = apdu.getBuffer();
    
            if (buf[ISO7816.OFFSET_CLA] == (byte)0xA0 && buf[ISO7816.OFFSET_INS] == (byte) 0xA4 && buf[ISO7816.OFFSET_P1] == (byte) 0x00&& buf[ISO7816.OFFSET_P2] == (byte) 0x00 
                    && buf[ISO7816.OFFSET_LC] == (byte) 0x02 && buf[ISO7816.OFFSET_LC + 1] == (byte) 0x7F  && buf[ISO7816.OFFSET_LC + 2] == (byte) 0x20) {
                ISOException.throwIt((short) 0x9F23);
            } else if (buf[ISO7816.OFFSET_CLA] == (byte) 0xA0 && buf[ISO7816.OFFSET_INS] == (byte) 0xC0  && buf[ISO7816.OFFSET_P1] == (byte) 0x00 
                    && buf[ISO7816.OFFSET_P2] == (byte) 0x00  && buf[ISO7816.OFFSET_P2+1] == (byte) 0x23 ) {
                Util.arrayCopyNonAtomic(res, (short) 0, buf, (short) 0, (short) 35);
                apdu.setOutgoingAndSend((short) 0, (short) 35);
    
            } else {
                ISOException.throwIt((short) 0x9090);
            }
        }
    }
    

    然后我将它安装为默认选择的小程序:

    CommandLine> gp -install e:\soq.cap --default
    
    CommandLine>
    

    然后我向它发送 APDU 命令:

    CommandLine> OSC.exe -s A0A40000027F20 -s a0c0000023
    Using reader with a card: ACS CCID USB Reader 0
    Sending: A0 A4 00 00 02 7F 20
    Received (SW1=0x9F, SW2=0x23)
    Sending: A0 C0 00 00 23
    Received (SW1=0x90, SW2=0x00):
    00 00 3B AD 3F 00 01 00 00 00 00 00 16 B3 03 06 ..;.?...........
    04 00 83 8A 83 8A 00 03 00 00 3B AD 00 00 3B AD ..........;...;.
    2F 06 02                                        /..
    

    它似乎如你所愿。

    【讨论】:

    • 亲爱的亚伯拉罕。这些是应该发生的请求和响应。请看下面并告诉我是否有可能(它来自 SIM APDU,正如您现在可能已经提到的那样)>> in:0xA0 A4 00 00 02 7F 20 0x9F 23 >> in:0xA0 C0 00 00 23
    • @MFA 关注this 问题以获得您的答案。
    • 谢谢,非常感谢您的帮助。
    • 非常感谢,我已经测试过了,但是你得到的和我得到的有所不同。就我而言,当卡收到0xa0c0000023 时,它会抛出一个异常,指出缓冲区中没有要发送的字节(此命令未在 PROCESS 函数中接收,我无法控制它),这意味着我的卡对@987654334 起作用@ 和0x00c0 一样。那么也许我们使用了不同类型的卡片?或者你对此有什么更好的解释?
    • @MFA 你用什么工具向卡发送 APDU 命令?似乎您的工具将0xa0c0000023 视为CLA=0xA0INS=0xC0P1=0x00P2=0x00Lc = 0x23,而我的工具(OpenSC-Tool)将其视为@987654341 @、INS=0xC0P1=0x00P2=0x00Le = 0x23 并且作为您的工具,将 0x23 视为 Lc(APDU 命令数据字段的长度),它需要 0x23 字节的数据在缓冲区中发送。你也可以试试我的工具吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多