首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用javax.smartcardio实现智能卡的ISO 7816 APDU

使用javax.smartcardio实现智能卡的ISO 7816 APDU
EN

Stack Overflow用户
提问于 2012-12-11 15:20:51
回答 3查看 5.4K关注 0票数 1

我已经使用javax.smartcardio读取智能卡上的序列号,而不费太大力气。然而,现在我被指派在空白卡上创建MF (如果没有这个序列号就不能读取),我正在按照ISO 7816准则创建APDU命令,但是无法创建正确的APDU命令,因为我的十六进制值被转换成了错误的字节。

代码语言:javascript
复制
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();
            }
        }       
    }
}

我有两个问题

1:命令APDU中的数据正在接受一个错误的字节(标记为*)。

2: SW1和SW2作为6A80返回,这意味着数据字段中的参数是不正确的(我猜是因为在将int转换为十六进制格式时出现了负值,但我不得不这样做。

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

我认为问题在于创建APDU的方式,可能是负值问题(虽然我创建Applet是为了从卡片中读取序列号,但我对java APDU的内容并不十分精通)。

EN

回答 3

Stack Overflow用户

发布于 2012-12-13 08:10:43

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

其他想法: ISO Create File的命令数据字段应该以类似于FCI的0x6X开头。您的0x21可能是整个模板的长度(应该以LC的形式发送),java根据字节数组的长度构造自己,所以尝试将其排除在外。第三个字节是0x1F,意思是0x21减号和长度,这一事实支持这一假设。

票数 2
EN

Stack Overflow用户

发布于 2014-05-22 06:39:43

我试过这样的命令:

。。

。。

代码语言:javascript
复制
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.Smart can。*;我和您有同样的问题,我不能使用该图书发送任何命令。但是有人说,我必须使用一些java包装来发送一些命令。嗯..。我还在努力.:-)

票数 0
EN

Stack Overflow用户

发布于 2013-07-31 06:08:26

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

代码语言:javascript
复制
Integer class = StringUtil.parseHex("your class as string");

类StringUtil

代码语言:javascript
复制
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;
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13822879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档