java - iaik pkcs#11 包装器和 java.lang.NoSuchMethodError

标签 java nosuchmethoderror pkcs#11 iaik-jce

我正在尝试从 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,上面的代码可以正常运行。但最初的问题仍未解决。

编辑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

最佳答案

异常

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

声明应调用签名为 void C_Initialize(Object o, boolean b) 的方法,但该方法不存在。您的猜测是正确的 所以我猜 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);
            }
        }
    }
}

编辑 2 海报 java.lang.NoSuchMethodError 的异常与混合 DLL 和 JAR 版本无关,因为这会生成 java.lang。不满意的链接错误

再次尝试获取错误原因

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

关于java - iaik pkcs#11 包装器和 java.lang.NoSuchMethodError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20226366/

相关文章:

java - PMD/CPD : Ignore bits of code using comments

java - Android 的套接字扫描

java - 未知对象的调用方法

pkcs#11 - 如何使用 PKCS11Interop 获取加密 token (智能卡)的密码失败计数

java - PKCS#11 keystore 在成功尝试输入密码后不验证密码

encryption - 使用 openssl 封装 PKCS11 key

java - 真正高质量和复杂的 Swing 组件在哪里?

java - 当一个人只能调用一个方法时,为什么要使用 `java.util.function.supplier` ?

java - "java.lang.NoSuchMethodError: org.apache.commons.fileupload.FileUploadBase.isMultipart"请帮我解决这个异常

java - ConcurrentHashMap 怎么可能没有 keySet() 方法呢?