Java智能卡问题//卡提供商配置



我有一个看似简单的任务,即从芯片卡读取未加密的数据与Java。我对智能卡毫无经验,我希望有人能给我指一下正确的方向。

我用javax创建了一个项目。smartcardio库,虽然它像我的信用卡一样有魅力(识别读卡器,识别购物车插入,建立卡连接),但它不适用于我试图读取的卡。

问题是该卡不符合智能卡标准(我相信),因为当我将该卡插入读卡器时,我得到了SCARD_E_NO_SMARTCARD错误。

我没有关于数据如何实际存储在卡上的任何文档,但我想(如果可能的话)只是戳一下,弄清楚它。我也不需要写入卡片,只需要读取存储在卡片上的数据。

我想创建一个CardTerminal实现,允许我只是发送任意命令到卡,而不是启动一个协议。

这是我的:

import java.util.List;
import javax.smartcardio.*;
public class SReader {
public static int listCounted() {
TerminalFactory factory = TerminalFactory.getDefault();
try {
List terminals = factory.terminals().list();
CardTerminal ter = (CardTerminal)terminals.get(0);
ter.waitForCardPresent(3000000);
if(ter.isCardPresent())
{
System.out.println("Card present");
// this causes the issue
Card ca = ter.connect("*");
System.out.println(ca);
}
System.out.println( ((CardTerminal)terminals.get(0)).isCardPresent());
return terminals.size();
} catch (CardException e) {
e.printStackTrace();
}
return 0;
}
public static void main(String[] args) {
listCounted();
}
}

,这是我插入卡片时得到的错误信息:

Card present
javax.smartcardio.CardNotPresentException: No card present
at java.smartcardio/sun.security.smartcardio.TerminalImpl.connect(TerminalImpl.java:83)
at Smaca/com.Smaca.SReader.listCounted(SReader.java:35)
at Smaca/com.Smaca.SReader.main(SReader.java:58)
Caused by: sun.security.smartcardio.PCSCException: SCARD_E_NO_SMARTCARD
at java.smartcardio/sun.security.smartcardio.PCSC.SCardConnect(Native Method)
at java.smartcardio/sun.security.smartcardio.CardImpl.<init>(CardImpl.java:97)
at java.smartcardio/sun.security.smartcardio.TerminalImpl.connect(TerminalImpl.java:79)
... 2 more

我想我需要写一个自定义的TerminalFactory实现能够读取卡?我已经搜索了好几天,想找到一个关于如何做到这一点的例子,但没有找到任何有用的东西。我也不确定这种方法是否适合我想要实现的目标。

任何允许我这样做的跨平台解决方案(node.js, python, Java)都可以。

任何帮助都非常感谢!

谢谢,汤姆

您的卡是同步I2C存储卡(AT24C16)。与异步卡不同,你的读卡器必须显式地支持它。

查看您的阅读器文档并检查是否(以及哪些)支持I2C存储卡。

如果您的读卡器支持I2C卡,那么应该描述如何与此特定卡通信。可能的选项通常是:

  • 使用特殊的APDU命令—这种方式可以直接在java中使用javax.smartcardio

  • 使用额外的阅读器API—您可能需要离开javax.smartcardio并使用一些供应商提供的库(几乎总是本机)并从java(例如使用JNA)调用它

如果您的读卡器不支持这张卡,您必须换另一个读卡器。对于java,首选带有APDU接口的阅读器(见上文)。

EDIT>

对于伪apdu,您需要使用"direct"模式连接到阅读器(这意味着您想直接与阅读器通信):

Card ca = ter.connect("direct");

那么伪apdu应该可以工作。AT24C16的典型通信序列如下(参见《ACR39系列-参考手册》第8.2节)。):

  • SELECT_CARD_TYPE——FF A4 00 00 01 02(type 0x02 for 32、64、128、256、512和1024千比特I2C卡)

  • SELECT_PAGE_SIZEFF 01 00 00 01(0x04 for 16 byte page)

  • ,READ_MEMORY_CARD/WRITE_MEMORY_CARD根据需要

祝你项目顺利!

相关内容

最新更新