首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaFX应用程序:找不到SunPKCS11类

JavaFX应用程序:找不到SunPKCS11类
EN

Stack Overflow用户
提问于 2014-02-12 15:21:57
回答 1查看 1.1K关注 0票数 0

我正在开发一个使用eToken专业版签名pdf的JavaFX应用程序。sign方法可以在普通的Java项目中完美地运行。而当在JavaFX应用程序中运行时,它总是遇到这样的异常:

代码语言:javascript
复制
Exception in Application start method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.javafx.main.Main.launchApp(Main.java:698)
    at com.javafx.main.Main.main(Main.java:871)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:403)
    at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47)
    at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115)
    at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.NoClassDefFoundError: sun/security/pkcs11/SunPKCS11
    at javafxapplication3.JavaFXApplication3.start(JavaFXApplication3.java:21)
    at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:319)
    at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:216)
    at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179)
    at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:176)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:176)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:17)
    at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:67)
    ... 1 more
Caused by: java.lang.ClassNotFoundException: sun.security.pkcs11.SunPKCS11
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 12 more
Java Result: 1

我用来签署pdf的代码如下:

代码语言:javascript
复制
@Override
    public void start(Stage primaryStage) {
        Signer signer = new Signer(new File("C:/Users/Adam/Desktop/pdf/hello.pdf"));
        signer.signWithToken(true);
    }

类签名者的代码如下:

代码语言:javascript
复制
public class Signer {

// define the file to be signed
private final File file;
private static String smartcardDllPath;
private static int level;
private static String reason;
private static String src;
private static String dest;
private static String location;
private static Collection<CrlClient> crlList;
private static OcspClient ocspClient;
private static TSAClient tsaClient;
private static final String DLL = "C:/Windows/System32/eTPKCS11.dll";

public Signer(File theFile) {
    location = "HK SAR";
    smartcardDllPath = null;
    file = theFile;
}


public void signWithToken(boolean certified) {
    try {
        String config = "name=eToken\nlibrary=" + DLL + "\nslotListIndex=" + getSlotsWithTokens(DLL)[0];
        ByteArrayInputStream bais = new ByteArrayInputStream(config.getBytes());
        Provider providerPKCS11 = new SunPKCS11(bais);
        Security.addProvider(providerPKCS11);
        configureParameters(certified);

        // create PdfSignatureAppearance
        PdfSignatureAppearance appearance = getPdfSigAppearance();
        // configure the keystore, alias, private key and certificate chain
        char[] pin = "love4Sakura".toCharArray();
        KeyStore ks = KeyStore.getInstance("PKCS11");
        ks.load(null, pin);
        String alias = (String) ks.aliases().nextElement();
        PrivateKey pk = (PrivateKey) ks.getKey(alias, null);
        Certificate[] chain = ks.getCertificateChain(alias);

        printChainInfo(chain);
        // configure the CRL, OCSP and TSA
        configCrlOcspTsa(chain);
        // create the signature
        ExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, "SunPKCS11-eToken");
        ExternalDigest digest = new BouncyCastleDigest();
        MakeSignature.signDetached(appearance, digest, pks, chain, crlList, ocspClient,
                tsaClient, 0, MakeSignature.CryptoStandard.CMS);

    } catch (IOException | DocumentException | GeneralSecurityException ex) {
        Logger.getLogger(Signer.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private static long[] getSlotsWithTokens(String libraryPath) {
    CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
    String functionList = "C_GetFunctionList";
    initArgs.flags = 0;
    PKCS11 tmpPKCS11 = null;
    long[] slotList = null;
    try {
        try {
            tmpPKCS11 = PKCS11.getInstance(libraryPath, functionList, initArgs, false);
            System.out.println(tmpPKCS11.toString());
        } catch (IOException ex) {
            try {
                throw ex;
            } catch (IOException ex1) {
                Logger.getLogger(Signer.class.getName()).log(Level.SEVERE, null, ex1);
            }
        }
    } catch (PKCS11Exception e) {
        try {
            initArgs = null;
            tmpPKCS11 = PKCS11.getInstance(libraryPath, functionList, initArgs, true);
        } catch (IOException | PKCS11Exception ex) {
        }
    }
    try {
        slotList = tmpPKCS11.C_GetSlotList(true);
        for (long slot : slotList) {
            CK_TOKEN_INFO tokenInfo = tmpPKCS11.C_GetTokenInfo(slot);
            System.out.println("slot: " + slot + "\nmanufacturerID: "
                    + String.valueOf(tokenInfo.manufacturerID) + "\nmodel: "
                    + String.valueOf(tokenInfo.model));
        }
    } catch (PKCS11Exception ex) {
        Logger.getLogger(Signer.class.getName()).log(Level.SEVERE, null, ex);
    }
    return slotList;
}

在你们回答之前:我想强调的是,我在一个普通的Java项目中完美地引用了Signer类。所以我不认为这是32位或64位的问题。另外,我使用的是32位JDK 1.7

EN

回答 1

Stack Overflow用户

发布于 2016-12-29 14:53:18

这个问题可能是因为不受支持的java.Do one thing版本,为此下载特定的jar文件并将其包含在您的项目中,它将为您工作。

您可以从以下链接下载jar - http://www.docjar.com/jar/sunpkcs11.jar

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21721231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档