从Linux 64位访问javax.smartcardio

Gil*_*zan 22 java smartcard pcsc

我正在尝试使用javax.smartcardio API加载智能卡终端,代码如下:

public CardTerminal getReadyCardTerminal() throws CardException {

    TerminalFactory factory = TerminalFactory.getDefault();
    CardTerminals terminals = factory.terminals();
    List<CardTerminal> list = terminals.list(State.CARD_PRESENT);

    while (list.isEmpty()) {
        terminals.waitForChange(1000);
        list = terminals.list(State.CARD_PRESENT);
    }
    CardTerminal cardTerminal = list.get(0);
    return cardTerminal;
}
Run Code Online (Sandbox Code Playgroud)

...而且我总是得到以下异常:

java.lang.IllegalStateException: no terminals
at javax.smartcardio.TerminalFactory$NoneCardTerminals.waitForChange(TerminalFactory.java:145)
Run Code Online (Sandbox Code Playgroud)

在Windows Vista/7上一切正常,但我不能让它在Linux上运行.我正在使用Ubuntu 12.04 64位.

我使用以下命令安装了pcscd服务:

sudo apt-get install libccid pcscd libpcsclite-dev libpcsclite1
sudo service pcscd start
Run Code Online (Sandbox Code Playgroud)

pcsc_scan命令打印出来:

PC/SC device scanner
V 1.4.18 (c) 2001-2011, Ludovic Rousseau <ludovic.rousseau@free.fr>
Compiled with PC/SC lite version: 1.7.4
Using reader plug'n play mechanism
Scanning present readers...
0: OMNIKEY CardMan 3x21 00 00

Tue Sep 11 15:44:49 2012
Reader 0: OMNIKEY CardMan 3x21 00 00
  Card state: Card inserted, 
  ATR: <some hexa codes>
  ...
Run Code Online (Sandbox Code Playgroud)

所以一切看起来都不错,但智能卡只是不起作用.我正在尝试使用Oracle和OpenJDK 1.7.0_05,32和64位.

在Ubuntu 32位环境下,代码可以运行OpenJDK(但不是Oracle JDK,不知道为什么).所以我认为从Java到PC/SC库的64位桥接器存在问题.

有任何想法吗?

谢谢.

小智 35

我想我找到了一个解决方法,因为我遇到了类似的问题.在来自ubuntu的bug报告中,它说javax.smartcardio库在错误的目录中搜索PC/SC库.

通过在我的机器上指定PC/SC库的路径,就像bugreport提到的那样,我得到了它的工作.

bug报告中的路径对我来说是错误的,我在64位fedora上,其中pc/sc库安装在/usr/lib64/libpcsclite.so.1

所以我的解决方法是指定java的库路径,如下所示:

java -Dsun.security.smartcardio.library=/usr/lib64/libpcsclite.so.1
Run Code Online (Sandbox Code Playgroud)

根据您的Linux发行版,libpcsclite.so.1实际位置可能会有所不同,也可能在/lib/x86_64-linux-gnu/libpcsclite.so.1(即Kubuntu 15.04).在这种情况下,将其称为:

java -Dsun.security.smartcardio.library=/lib/x86_64-linux-gnu/libpcsclite.so.1
Run Code Online (Sandbox Code Playgroud)


小智 7

我正在使用带有debian arm版本的覆盆子

首先找到libpcsclite的位置:

$ ldd -r /usr/bin/pcsc_scan
Run Code Online (Sandbox Code Playgroud)

然后使用libpcsclite位置:

java -Dsun.security.smartcardio.library=/usr/lib/arm-linux-gnueabihf/libpcsclite.so.1
Run Code Online (Sandbox Code Playgroud)


Ash*_*era 6

调用程序时需要提供 libpcsclite.so.1 的路径,如下所示

java -Dsun.security.smartcardio.library=/path/to/libpcsclite.so.1

如果您不知道库的路径,请使用以下命令

find /usr/lib -name libpcsclite.so.1
Run Code Online (Sandbox Code Playgroud)

这通常会显示您计算机上的路径。我在 Ubuntu 10(32 位)和 Ubuntu 15(32 位和 64 位)上都使用了它

如果你像我一样懒,你可以做的是在使用 javax.smartcardio 库之前将这部分代码包含在你的程序中

      try {
            String comm[] = { "find", "/usr", "/lib", "-name",
                    "libpcsclite.so.1" };
            Process p = Runtime.getRuntime().exec(comm);

            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(p.getInputStream()));

            while ((line = reader.readLine()) != null && !line.equals("")) {
                if (line.contains("libpcsclite.so.1")) {
                System.setProperty("sun.security.smartcardio.library",line);
                    break;
                }

            }
            p.waitFor();

        } catch (Exception e) {

            e.printStackTrace();
        }
Run Code Online (Sandbox Code Playgroud)

现在您可以照常运行代码,而无需包含 libpcsclite.so.1 的路径