簡體   English   中英

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

[英]ISO 7816 APDU for Smart Card using javax.smartcardio

我已經使用javax.smartcardio地從智能卡讀取序列號。 但是現在我被分配在空白卡上創建MF(無法讀取序列號)。我正在按照ISO 7816准則為此創建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%正確,並經過測試,因為我已經成功地使用智能卡工具在空白卡中創建了MF命令我現在想在Java中做同樣的事情。

我認為問題在於創建此APDU的方式,可能是負值問題(盡管我已經創建了Applet來從卡中讀取序列號,但我對Java APDU的知識不是很熟練)。

如您所言,您手頭有一條有效的命令,並且一定要仔細檢查其Java表示形式:您確定該命令在先前的嘗試中沒有成功執行嗎? (顯然只允許一個MF。)問題是,報告的錯誤代碼與“已知的正確APDU”假設相矛盾,這是我能想到的唯一解決方案。 就給出的而言,Java代碼看起來正確。

另一個想法:ISO創建文件的命令數據字段應以FCI的0x6X開頭。 可能您的0x21是整個模板的長度(假定將以LC形式發送),java會根據字節數組的長度來構造自身,因此請嘗試將其忽略。 第三個字節為0x1F,即0x21減去標簽和長度,這一事實支持了這一假設。

我已經嘗試過以下命令:

..

..

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包裝器來發送一些命令。 嗯...我還在努力呢... :-)

您需要通過以下方法將字節正確轉換為十六進制。

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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM