[英]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.