首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从智能卡读取数据(CNS/CNR)

从智能卡读取数据(CNS/CNR)
EN

Stack Overflow用户
提问于 2018-10-17 20:49:37
回答 1查看 1.5K关注 0票数 1

我用java卡编写了一个程序,允许我从智能卡中读取一些数据。卡的文件系统结构如下:

智能卡文件系统

智能卡是意大利公共行政部门的名片。

我可以正确地连接到卡,通过运行以下代码将数据读取命令发送到路径MF/DF1/EF_Dati_Personali路径

当我试图进入DF2/Dati_personali_aggiuntivi,我找不到任何数据,尽管它们是存在的。

根据参考指南,要进入DF1和DF2地区,各部门如下:

数据部门

下面是我写的代码。代码在行中进行注释,以获取数据以识别问题。

有人能告诉我我哪里错了吗?每一项建议都会受到赞赏。非常感谢

代码语言:javascript
复制
package smartcard;

import java.io.IOException;
import static java.lang.System.out;
import java.util.List;
import javax.smartcardio.ATR;
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;
import javax.swing.JOptionPane;

public class SmartCard {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws CardException, IOException {
        try {
             TerminalFactory factory = TerminalFactory.getDefault();
            List<CardTerminal> terminals = factory.terminals().list();
            System.out.println("Terminals: " + terminals);

            // Use the first terminal
            CardTerminal terminal = terminals.get(0);

            // Connect wit hthe card
            Card card = terminal.connect("*");
            System.out.println("card: " + card);
            CardChannel channel = card.getBasicChannel();

            //GET ATR
            ATR atr = card.getATR();

            byte[] ATR = atr.getBytes();
            System.out.println("Card ATR: " + bytesToHex(ATR));
           //   // originale

            //GET SELECT_FILE_APDU
            byte[] READ_BINARY_APDU = {(byte) 0x00, (byte) 0xB0, (byte) 0x00, (byte) 0x00, (byte) 0xff}; 

            byte[] dati_personali = {(byte) 0x00, (byte) 0xA4, (byte) 0x08, (byte) 0x00, (byte) 0x04, (byte) 0x11, (byte) 0x00, (byte) 0x11, (byte) 0x02, (byte) 0x00};
            // Whit this String I can correctly read DF1 Data of CNS (Carta Nazionale servizi)

            // This should be the string for get DF2 data but I cannot find anything.
            byte[] dati_personali_aggiuntivi = {(byte) 0x00, (byte) 0xA4, (byte) 0x08, (byte) 0x00, (byte) 0x04, (byte) 0x12, (byte) 0x00, (byte) 0x12, (byte) 0x01, (byte) 0x00};

            String dati_personali_string = richiedi(channel, READ_BINARY_APDU, dati_personali, "<b>Dati personali:</b><br>");
            String dati_personali_aggiuntivi_string = richiedi(channel, READ_BINARY_APDU, dati_personali_aggiuntivi, "<b>Dati personali aggiuntivi:</b><br>");
            JOptionPane.showMessageDialog(null,"dati personali: "+ dati_personali_string, "Dati personali",JOptionPane.INFORMATION_MESSAGE);
            JOptionPane.showMessageDialog(null,"dati personali agiguntivi: "+ dati_personali_aggiuntivi_string, "Dati personali aggiuntivi",JOptionPane.INFORMATION_MESSAGE);


            // Disconnect the card
            card.disconnect(false);
            System.out.println("DISCONEESSO ");

        } catch (Exception e) {
            System.out.println("Ouch: " + e.toString());
        }

    }

    public static String richiedi(CardChannel channel, byte[] read, byte[] select, String titolo) throws CardException {
        out.println(titolo);
        // Send Select Applet command
        ResponseAPDU answer = channel.transmit(new CommandAPDU(select));
        // Send test command
        answer = channel.transmit(new CommandAPDU(read));
        byte r[] = answer.getData();
        String test = "";
        for (int i = 0; i < r.length; i++) {
            test += (char) r[i];
        }
        System.out.print(test);
        out.println(test);
        out.println("<br><br>");
        return test;
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            sb.append(String.format("%02x", bytes[i]));
        }
        return sb.toString();
    }
}

更新APDU跟踪

代码语言:javascript
复制
REQUEST: Dati personali:
read command: >>> 00b00000ff
select command: >>> 00a40800041100110200

RESPONSE: Dati personali:
<<< answer from CNS: 303030303733303436303330303830373039323031303038303730393230313630384954414c49414e4f3130414e544f4e494f20435249535449414e3038323230343139383230314d30303130544c4e4e4e43383244323246323035493030303446323035303030303034463230353030303000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000

_____________________
REQUEST: Dati personali aggiuntivi:
read command: >>> 00b00000ff
select command: >>> 00a40800041200120100

RESPONSE: Dati personali aggiuntivi:
<<< answer from CNS: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000
EN

回答 1

Stack Overflow用户

发布于 2018-10-18 10:06:04

根据给定的跟踪,您的代码正确工作,并且成功读取了卡中的数据--基本文件‘DF2 2/Dati_personali_aggi头vi’被填充为零。

符合文献资料 (第4.3节):

EF.Dati_personali_aggiuntivi -l‘’interoèposto‘00’

使用谷歌翻译:

EF.Additional_personal_dates -整个内容被设置为‘00’十六进制

一些补充说明:

  • “EF.Dati_personali”文件包含400个字节--您可能需要使用几个“读取二进制”命令来获取它们。
  • 始终检查APDU响应状态(‘9000’) -- ResponseAPDU.getSW()对此非常有用

祝你的项目好运!

EDIT> OpenSC支持CNS卡(参见这里这里) --您可能想试一试

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52863397

复制
相关文章

相似问题

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