1

我已经习惯javax.smartcardio了从智能卡中读取序列号而不费力气。但是现在我被分配在空白卡上创建 MF(没有它无法读取序列号)。我正在根据 ISO 7816 指南为此创建 APDU 命令,但无法创建正确的 APDU 命令,因为我的十六进制值是转换为错误的字节。

import javax.smartcardio.Card;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.CommandAPDU;
import javax.smartcardio.ResponseAPDU;
import javax.smartcardio.TerminalFactory;

class SmartCardAPIs {

    public int Create_MF() throws CardException{

        //--Variable declaration
        int result=0;
        Card card=null;     
        byte[] responseData=null;
        ResponseAPDU answer=null;
        String SW1=null;
        String SW2=null;
        int cla,  ins,  p1,  p2;
        byte[] data=null;
        //---------------------------------------------

        //--1--Establish connection with the smart card
        TerminalFactory factory = TerminalFactory.getDefault();
        List<CardTerminal> terminals = factory.terminals().list();
        // Use the first terminal
        CardTerminal terminal = terminals.get(0);
        // Connect with the card
        card = terminal.connect("*");
        CardChannel channel = card.getBasicChannel();           
        //---------------------------------------------

        //--2--Create MF 
        cla=0x00;
        ins=0xE0;
        p1=0x00;
        p2=0x00;
        data = new byte[] {
            (byte) 0x21,
            (byte) 0x62,
            (byte) 0x1F,
            (byte) 0x82, // **** Getting converted to -126 ****
            --
            --
            --
        };          
        answer = channel.transmit(new CommandAPDU(cla,  ins,  p1,  p2, data));
        responseData= answer.getBytes();

        if(responseData!=null)
        {
            if(responseData.length==2)
            {
                SW1=String.format("%02X ", (responseData[0])).trim();
                SW2=String.format("%02X ", (responseData[1])).trim();
            }
        }       
    }
}

我有2个问题

1:命令 APDU 中的数据占用了一个错误的字节(标记为*)。

2:SW1 和 SW2 返回为 6A 80,这意味着数据字段中的参数不正确(我猜是因为将十六进制格式的 int 转换为字节时为负值,但由于我被迫这样做,所以无济于事)。

我在这里放置的部分 APDU 命令是我提供的完整命令的一部分,并且该命令是 100% OK 并且经过测试,因为我已经成功地使用带有命令的智能卡工具在空白卡中创建 MF .我现在想在java中做同样的事情。

我认为问题出在创建此 APDU 的方式上,可能是负值问题(尽管我创建了 Applet 以从卡中读取序列号,但我对 java APDU 的东西不是很熟悉)。

4

3 回答 3

2

既然您说,您手头有一个工作命令,并且肯定仔细检查了它的 java 表示:您有多确定该命令在之前的尝试中没有成功执行?(显然只允许一个 MF。)问题是,报告的错误代码与“正确的 APDU 已知”假设相矛盾,这是我能想到的唯一解决方案。就给出的而言,Java 代码看起来是正确的。

其他想法:ISO 创建文件的命令数据字段应该以 FCI 的 0x6X 之类的开头。可能您的 0x21 是整个模板的长度(应该作为 LC 发送),java 从字节数组的长度构造自身,因此请尝试将其省略。第 3 个字节是 0x1F,即 0x21 减去标签和长度,这一事实支持了这一假设。

于 2012-12-13T08:10:43.707 回答
0

我试过这个命令:

..

..

private static final byte[] Select_App = {(byte)0x00,(byte)0xA4,(byte)0x04,(byte)0x00,(byte)0x04,(byte)0x50,(byte)0x54,(byte)0x4B,(byte)0x65};

......

他们工作得很好,我从卡上得到了正确的回应。但我在android上试过这个命令。所以我认为字节转换是正确的,我们不需要转换任何东西

好吧,关于 java.smartcardio.*; 我和你有同样的问题,我无法使用该库发送任何命令。但是有人说我必须使用一些 java wrapper 来发送一些命令。嗯...顺便说一句,我仍在努力... :-)

于 2014-05-22T06:39:43.043 回答
-1

您需要通过以下方法将字节正确转换为十六进制。

Integer class = StringUtil.parseHex("your class as string");

类 StringUtil


public class StringUtil {
public static Integer parseHex(String iStr) {
    int mask = 255;
    if (iStr.length() > 2)
        mask = 65535;
    try {
        return Integer.valueOf(Integer.parseInt(iStr, 16) & mask);
    } catch (Exception ex) {
    }
    return null;
}
于 2013-07-31T06:08:26.913 回答