【问题标题】:iaik pkcs#11 wrapper and java.lang.NoSuchMethodErroriaik pkcs#11 包装器和 java.lang.NoSuchMethodError
【发布时间】:2013-11-26 19:36:56
【问题描述】:

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

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,上面的代码可以正常工作。但最初的问题仍未解决。

EDIT2:

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

【问题讨论】:

    标签: java nosuchmethoderror pkcs#11 iaik-jce


    【解决方案1】:

    例外

     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 version 1.3PKCS#11 Wrapper version 1.2.15(找不到 1.2.17 的)。

    所以您的 DDL pkcs11wrapper.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);
                }
            }
        }
    }
    

    }

    edit 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 名称
    • 测试期望所有文件都在同一目录中

    【讨论】:

    • 您好,感谢您的回答,“pkcs11wrapper.dll”是 pkcs#11 包装包附带的。所以,我正在测试兼容的 jar 和 dll 版本,但仍然得到相同的异常。
    • @alikox 嗨,我做了一些调查,在你的库路径中似乎有 1.2.17 版的 DLL。请参阅上面我的答案中的 edit 部分。
    • 嗨,我试过你的代码,虽然它确实找到了三个 pkcs11 包装器 dll,它们都在同一个目录中。我编辑了我的问题以反映这一点。
    • 当它被报告 3 次时,这意味着您的 PATH 包含目录 `C:\Windows\system32` 的三倍(这不是一个真正的问题)。 DLL C:\Windows\system32\pkcs11wrapper.dll 的版本是什么? DLL 1.3 版本的文件大小为 99,328 字节。
    • 您好,它是包装 DLL 的 1.3 版。
    【解决方案2】:

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

    【讨论】:

    • 感谢您的回答,这是我更喜欢 IAIK 的 pkcs#11 提供程序而不是 Sun 提供的提供程序的原因之一。问候。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多