javax.smartcardio 读取所有智能卡
Posted
技术标签:
【中文标题】javax.smartcardio 读取所有智能卡【英文标题】:javax.smartcardio read all smart card 【发布时间】:2014-05-02 06:49:35 【问题描述】:我必须阅读 MASTERCARD、VISA、VISA ELECTRON 等的主帐号 (PAN)。我写了这段代码,但它不起作用,有人可以帮助我吗?
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;
public class LetturaSmartCard
public static void main(String[] args) throws CardException
// stampo lista lettori
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
System.out.println("Lista lettori smart card collegati: " + terminals);
// prendo il primo lettore
CardTerminal terminal = terminals.get(0);
System.out.println("Lettore utilizzato: " + terminal);
//stabilisco connessione con la carta
Card card = terminal.connect("*");
// System.out.println(card.getProtocol());
System.out.println("\n\nCarta inserita: " + card);
CardChannel channel = card.getBasicChannel();
ATR atr = card.getATR();
byte[] ATR = atr.getBytes();
byte[] TuttaCarta;
System.out.println("ATR della carta: " + LetturaSmartCard.bytesToHex(ATR));
//------------------------------------lettura---------------------------
byte[] selectVpay = (byte) 0x00, (byte) 0xA4, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x20, (byte) 0x20, (byte) 0x00;
byte[] selectMastercard = (byte) 0x00, (byte) 0xA4, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x10, (byte) 0x10, (byte) 0x00;
byte[] selectVisaElectron = (byte) 0x00, (byte) 0xA4, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x20, (byte) 0x10, (byte) 0x00;
byte[] bo = (byte) 0x00, (byte) 0xB2, (byte) 0x00, (byte) 0x03, (byte) 0x60;
byte[] selectMaestro = (byte) 0x00, (byte) 0xA4, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x30, (byte) 0x60, (byte) 0x00;
byte[] getProcessingOptions = (byte) 0x80, (byte) 0xA8, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x83, (byte) 0x00, (byte) 0x00;
byte[] readRecord = (byte) 0x00, (byte) 0xB2, (byte) 0x01, (byte) 0x0C, (byte) 0x00;
byte[] lettura = (byte) 0x00, (byte) 0xB0, (byte) 0x60, (byte) 0x10, (byte) 0x00;
ResponseAPDU r = null;
CommandAPDU capdu = new CommandAPDU(selectMastercard);
r = card.getBasicChannel().transmit(capdu);
TuttaCarta = r.getBytes();
System.out.println(LetturaSmartCard.bytesToHex(TuttaCarta));
capdu = new CommandAPDU(getProcessingOptions);
r = card.getBasicChannel().transmit(capdu);
TuttaCarta = r.getBytes();
System.out.println(LetturaSmartCard.bytesToHex(TuttaCarta));
capdu = new CommandAPDU(readRecord);
r = card.getBasicChannel().transmit(capdu);
TuttaCarta = r.getBytes();
System.out.println(LetturaSmartCard.bytesToHex(TuttaCarta));
//----------------------------------------------------------------------
// disconnect
card.disconnect(false);
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();
我不知道为什么它不起作用我的答案是
Lista lettori smart card collegati: [PC/SC terminal OMNIKEY CardMan 3x21 0]
Lettore utilizzato: PC/SC terminal OMNIKEY CardMan 3x21 0
Carta inserita: PC/SC card in OMNIKEY CardMan 3x21 0, protocol T=0, state OK
ATR della carta: 3b6800000073c84013009000
6f2d8407a0000000041010a522500a4d4153544552434152448701015f2d086974656e66726573bf0c059f4d020b0a9000
771282023900940c1002030118010200180404009000
**6985**
6985
是我在期待 PAN 时收到的错误。
我做错了什么?
【问题讨论】:
【参考方案1】:这个错误意味着卡上没有这样的记录。使用您的 READ RECORD 命令
00 B2 01 0C 00
您正在尝试使用 SFI 1 读取文件的记录 1。但是,您收到的响应 GET PROCESSING OPTIONS 命令的应用程序文件定位器明确指出卡上只有以下记录可用:
10 02 03 01: records 2 and 3 in the file with SFI 2
18 01 02 00: records 1 and 2 in the file with SFI 3
18 04 04 00: record 4 in the file with SFI 3
因此,您不能期望卡上出现 SFI 1 文件中的记录 1。对于该卡,您通常可以在 SFI 2 记录 2 中找到 PAN:
00 B2 02 14 00
另请注意,您使用的静态编码 GPO 命令仅适用于具有空 PDOL 的卡。
【讨论】:
以上是关于javax.smartcardio 读取所有智能卡的主要内容,如果未能解决你的问题,请参考以下文章
getATR() 不会在 javax.smartcardio 中重置智能卡
通过 javax.smartcardio 连接到 micro SD
使用 javax.smartcardio 读取 NFC Mifare Ultralight 卡
在 Open JDK 11(Redhat)上找不到 javax.smartcardio.*