1

我正在尝试从 iaik pkcs#11 包装器(1.3 版,最新的 atm)运行一个简单的示例代码,但随时NoSuchMethodError待命pkcs11Module.initialize

Module pkcs11Module = Module.getInstance("siecap11");
pkcs11Module.initialize(null); 
Slot[] slots = pkcs11Module.getSlotList(Module.SlotRequirement.TOKEN_PRESENT);
for (Slot s: slots) {
    System.out.println(s.getSlotID());
}
pkcs11Module.finalize(null);

异常堆栈跟踪如下

java.lang.NoSuchMethodError:     iaik.pkcs.pkcs11.wrapper.PKCS11.C_Initialize(Ljava/lang/Object;Z)V
at iaik.pkcs.pkcs11.Module.initialize(Module.java:308)
at test.pkcs11.Pkcs11Service.listSlotsWithTokens(Pkcs11Service.java:98)
at test.pkcs11.TestPkcs11Service.testListSlots(TestPkcs11Service.java:35)

类似的代码在 Linux 上运行良好,所以我猜 pkcs11wrapper.dll 有问题。

pkcs11wrapper.dllsiecap11.dllc\windows\system32目录中,并且都是 32 位模块。

我尝试了不同的 pkcs#11 提供程序、pkcs11wrapper 的调试和发布版本,但结果是相同的。

pkcs11wrapper.dll 的调试版本生成以下输出:

11/26/13 21:30:50   CALL: entering (in Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_initializeLibrary)
11/26/13 21:30:50   CALL: exiting  (in Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_initializeLibrary)
11/26/13 21:30:50   CALL: entering (in Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_connect)
11/26/13 21:30:50   INFO: connect to PKCS#11 module: siecap11 ...  (in Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_connect)
11/26/13 21:30:50   CALL: exiting  (in Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_connect)

智能卡附带的实用程序运行良好,opensc pkcs11-tool 也是如此。

编辑:

使用版本 1.2.17 的 pkcs11 包装库及其随附的 dll,上面的代码可以正常工作。但最初的问题仍未解决。

编辑2:

SubOptimal 建议的以下代码生成以下输出。

@Test
public void testFindLibrary() {
    String lineSeparator = System.getProperty("path.separator");
    String libraryPath = System.getProperty("java.library.path");
    for (String dir : libraryPath.split(lineSeparator)) {
        File f = new File(dir + "/" + "pkcs11wrapper.dll"); 
        if (f.exists()) {
            System.out.println("found in: " + f.getAbsolutePath());
        }
    }
}

输出:

found in: C:\Windows\system32\pkcs11wrapper.dll
found in: C:\Windows\system32\pkcs11wrapper.dll
found in: C:\Windows\system32\pkcs11wrapper.dll
4

3 回答 3

5

例外

 java.lang.NoSuchMethodError:     iaik.pkcs.pkcs11.wrapper.PKCS11.C_Initialize(Ljava/lang/Object;Z)V

声明一个带有签名的方法void C_Initialize(Object o, boolean b)应该被调用并且不存在。你的猜测是对的so i am guessing there is something wrong with pkcs11wrapper.dll.基于 Javadoc,这个方法签名已经改变 PKCS#11 Wrapper 版本 1.3PKCS#11 Wrapper 版本 1.2.15(找不到 1.2.17 的版本)。

所以你的 DDLpkcs11wrapper.dll是针对旧版本的。您可以在 Windows 下的文件属性菜单中查看版本。

编辑 似乎 1.2.17 版的 dll 位于 java.library.path 中的某个位置。我使用 iaikPkcs11Wrapper 存档中的 GetInfo.java 进行了以下测试。

dll      jar      result
1.2.17   1.2.17   work successful
1.2.17   1.3      java.lang.UnsatisfiedLinkError: iaik.pkcs.pkcs11.wrapper.PKCS11Implementation.C_Initialize(Ljava/lang/Object;Z)V
1.3      1.3      work successful
1.3      1.2.17   java.lang.UnsatisfiedLinkError: iaik.pkcs.pkcs11.wrapper.PKCS11Implementation.C_Initialize(Ljava/lang/Object;)V  

dll-1.2.17 和 jar-1.3 的组合会产生您的异常。

您可以运行以下代码以在意外位置找到 dll

import java.io.File;
class Scratch {
    public static void main(String[] args) {
        String lineSeparator = System.getProperty("path.separator");
        String libraryPath = System.getProperty("java.library.path");
        for (String dir : libraryPath.split(lineSeparator)) {
            if (new File(dir + "/" + "pkcs11wrapper.dll").exists()) {
                System.out.println("found in: " + dir);
            }
        }
    }
}

}

编辑 2海报的例外java.lang.NoSuchMethodError与混合 DLL 和 JAR 版本无关,因为这会产生一个java.lang.UnsatisfiedLinkError

另一个尝试获取错误原因

PKCS11Test.java

import iaik.pkcs.pkcs11.Module;
import iaik.pkcs.pkcs11.Info;
import iaik.pkcs.pkcs11.Slot;

public class PKCS11Test {
    public static void main(String[] args) throws Exception {
        Module pkcs11Module = Module.getInstance(args[0]);
        pkcs11Module.initialize(null);
        pkcs11Module.finalize(null);
    }
}

PKCS11Test.cmd

set CLASS=PKCS11Test
set JAR=iaikPkcs11Wrapper.1.3.jar
set PKCS11_DLL=%~dp0\opensc_pkcs11.dll
rem cp PKCS11Wrapper.1.3.dll pkcs11wrapper.dll
javac -cp %JAR% %CLASS%.java || pause && exit
java -cp %JAR%;. -Djava.library.path=%~dp0 %CLASS% %PKCS11_DLL%
  • 将 PKCS11_DLL 变量中的 DLL 名称替换为您的 DLL 的名称
  • 测试期望同一目录中的所有文件
于 2013-11-29T12:22:22.897 回答
2

与您的原始问题没有直接关系,但 suns 错误6880559及其重复项表明 Windows 64 位中的 pkcs11 实现存在一些问题。

于 2013-12-04T18:30:51.483 回答
0

移到新计算机后,问题消失了。java 库/系统路径中的某处可能存在另一个版本的 DLL。

于 2014-08-29T06:19:36.183 回答