当前位置: 首页 > 知识库问答 >
问题:

ISO 7816 APDU适用于使用javax.smartcardio的智能卡

马泓
2023-03-14

我已经使用了javax。smartcardio无需太多努力即可从智能卡读取序列号。然而现在我被指派在空白卡片上创建MF(没有它序列号就无法读取)。我正在根据ISO7816指南创建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();
            }
        }       
    }
}

我有两个问题

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

2: SW1和SW2返回为6A 80,这意味着数据栏中的参数是不正确的(我猜是因为负值,而将十六进制格式的int转换为字节,但不能帮助太多,因为我被迫这样做)。

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

我假设问题在于如何创建这个APDU,可能是负值问题(我不是很擅长java APDU的东西,虽然我已经创建了Applet读取序列号从卡)。

共有3个答案

彭坚壁
2023-03-14

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

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;
}
薛浩言
2023-03-14

我试过这个命令:

..

..

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。*;我和你有同样的问题,我不能用librari发送任何命令。但是有人说我必须使用一些java包装器来发送一些命令。嗯。。。顺便说一句,我仍在努力……:-)

鲁泰宁
2023-03-14

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

另一个想法是:ISO创建文件的命令数据字段应该以类似0x6X的内容开头,用于FCI。您的0x21可能是整个模板的长度(应该作为LC发送),java根据字节数组的长度构造它自己,所以请尝试忽略它。第三个字节是0x1F,意思是0x21减去标记和长度,这一事实支持了这一假设。

 类似资料:
  • 因此,我正在尝试编写一个小applet,它使用library。智能卡与读卡器连接,现在我成功连接到智能卡并读取基本信息,如ATR和协议(T=1)。 我对此做了一些研究(例如:http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_5_basic_organizations.aspx#table9) 但我不知道我应该向卡上发送哪

  • 问题内容: 是否有一些针对Java的智能日期/时间解析器库?聪明的意思是,我不需要指定日期/时间格式。该API应该与此类似: 更新 : 问题答案: JodaTime非常适合处理日期对象(例如date.plusDays(10)) …但是 JChronic 是您想要的自然语言日期解析,例如

  • 我对硒比较陌生。目前,在我的公司,我们使用Eclipse创建并运行测试自动化(Maven/Cucumber/Selenium)。我们还将IntelliJIDEA用于Java开发 我的问题是,是否可以像使用Eclipse(Maven/Ccucumber/Selenium)一样使用IntelliJ IDEA进行自动化测试?我的意思是构建测试自动化脚本。如果是,那么您可以推荐任何解释如何为Intelli

  • 我有一个智能表,我正在AngularJS工作。该表使用自定义管道来搜索和排序其数据。我还要求表具有工作分页,以及一个下拉框,以便您可以选择要显示的行数(想想数据)。 对于搜索和排序,自定义管道可以毫无问题地触发我的ajax请求。但是,当我单击任何页码或更改要显示的行数时,管道不会被触发。 页码似乎被设置为调用setPage(page)(这是由st pagination指令设置的),但是什么也没有发

  • 我尝试使用ACR1252U和javax.smartcardioJava库阅读NFC Mi的Ultralight卡(第4页): 有时它有效,有时无效(使用同一张卡) 当阅读起作用时,我得到以下值: ATR = 0x3B8F8001804F0CA0000003060300030000000068 SW1 = 0x90 SW2 = 0x00 当它不起作用时,我会得到这些: < li>ATR = 0x3B

  • 我设置了密码缓存,但奇怪的是我认为我已经这样做了。从一封电子邮件到github,他们似乎改变了一些事情: 你好Thufir 您看到的是,默认情况下,所有新创建的repo现在都使用智能HTTP而不是SSH。我们这里有一篇帮助文章,解释了如何在此处进行更改:https://help.github.com/articles/why-is-git-always-asking-for-my-password