java - Xades4j: keystore 无法初始化

标签 java certificate keystore xades4j

我正在尝试将最近在 Windows 中安装的证书导入到 Java 中以与 xades4j 一起使用。不幸的是,我对证书和 key 等方面还很陌生。

但是每次运行该程序时,都会收到以下错误:

>xades4j.verification.UnexpectedJCAException: The keystore couldn't be initialized
    at xades4j.providers.impl.KeyStoreKeyingDataProvider.ensureInitialized(KeyStoreKeyingDataProvider.java:179)
    at xades4j.providers.impl.KeyStoreKeyingDataProvider.getSigningCertificateChain(KeyStoreKeyingDataProvider.java:189)
    at xades4j.production.SignerBES.sign(SignerBES.java:159)
    at xades4j.production.SignerBES.sign(SignerBES.java:130)
    at com.logic.test.signBes(test.java:138)
    at com.logic.test.<init>(test.java:80)
    at com.view.FrmMenu.<init>(FrmMenu.java:41)
    at com.view.FrmMenu$9.run(FrmMenu.java:289)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.security.KeyStoreException: KeyStore instantiation failed
    at java.security.KeyStore$Builder$FileBuilder.getKeyStore(KeyStore.java:1862)
    at xades4j.providers.impl.KeyStoreKeyingDataProvider.ensureInitialized(KeyStoreKeyingDataProvider.java:175)
    ... 21 more
Caused by: java.io.IOException: DER input, Integer tag error
    at sun.security.util.DerInputStream.getInteger(DerInputStream.java:192)
    at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1940)
    at java.security.KeyStore.load(KeyStore.java:1445)
    at java.security.KeyStore$Builder$FileBuilder$1.run0(KeyStore.java:1848)
    at java.security.KeyStore$Builder$FileBuilder$1.run(KeyStore.java:1807)
    at java.security.KeyStore$Builder$FileBuilder$1.run(KeyStore.java:1796)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.KeyStore$Builder$FileBuilder.getKeyStore(KeyStore.java:1858)
    ... 22 more
>

我需要使用 XaDeS-BES 格式签署 XML 文档。我已从光盘导入 key (或证书?),它位于 Windows 受信任的根证书颁发机构证书中。我从 Windows 证书管理器 (certmgr.msc) 将其导出到 C 驱动器的根目录。

我找到了one post on this website提到尝试以下方法来初始化 KeyStore:

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    ks.load(null, null);

不幸的是,没有任何变化。

我使用的代码基于 the example wiki :

private static final String CERT_FOLDER = "C:/";
private static final String CERT        = "testkey.cer";

private static final String PASS        = "test1234"; //the same in cert and keystorage
private static final String SIGNED      = "persistent/xml/001-001-000000000new1.xml";
private static final String DOCUMENT    = "persistent/xml/001-001-000000000.xml";

private static void signBes() throws Exception {
    Document doc = DocumentBuilderFactory
            .newInstance()
            .newDocumentBuilder()
            .parse(new File(DOCUMENT));
    Element elem = doc.getDocumentElement();
    DOMHelper.useIdAsXmlId(elem);

    KeyingDataProvider kdp = new FileSystemKeyStoreKeyingDataProvider(
            "pkcs12",
            CERT_FOLDER + CERT,
            new FirstCertificateSelector(),
            new DirectPasswordProvider(PASS),
            new DirectPasswordProvider(PASS),
            true);
    DataObjectDesc obj = new DataObjectReference("#" + elem.getAttribute("Id"))
            .withTransform(new EnvelopedSignatureTransform());
    SignedDataObjects dataObjs = new SignedDataObjects().withSignedDataObject(obj);

//        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
//        ks.load(null, null);

    XadesSigner signer = new XadesBesSigningProfile(kdp).newSigner();
    signer.sign(dataObjs, elem);

    TransformerFactory tFactory = TransformerFactory.newInstance();
    Transformer transformer = tFactory.newTransformer();
    DOMSource source = new DOMSource(doc);        
    StreamResult result = new StreamResult(new File(SIGNED));
    transformer.transform(source, result);
}

感谢您提供的所有帮助。

最佳答案

要执行签名操作,您需要一个 key /证书,即 PKCS12 容器。在 Windows 上,该对通常是 .pfx.p12 文件。我不确定问题是什么,但以下一些注意事项可能会对您有所帮助:

  • 用于签名的证书通常是“个人”证书,而不是受信任的颁发机构根证书。
  • 根证书是属于通常向其他主体颁发证书的实体的证书。
  • 验证证书过程的一部分是建立从主体证书到根证书的信任链。在 Windows 上,受信任的根证书位于您提到的商店:“Windows 受信任的根证书颁发机构”。您的签名证书可能不应该在那里。
  • 由于您正在执行签名操作(对于 BES 签名)并使用 FileSystemKeyStoreKeyingDataProvider,因此信任链实际上不太相关。当您验证签名时,它就会变得相关。
  • 从您的代码来看,您似乎有一个仅证书文件(.cer)。我不知道您最初是如何获得证书的,但应该与 key 一起提供,可能捆绑在受密码保护的 .pfx 文件中。
  • 创建 FileSystemKeyStoreKeyingDataProvider 时,您应该 传递 PKCS12 文件(例如 .pfx)
  • 如果您在其他 Windows 商店中安装了证书,请尝试使用 key 将其导出(如果可能;取决于最初导入的方式)。

希望这有帮助。

关于java - Xades4j: keystore 无法初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54404810/

相关文章:

java - 多个 keystore 与多个 key 以及 key 的导出/导入

java - Sonar 占用太多空间和时间

java - LinkedBlockingQueue 中 put() 的性能

ssl - IIS 6.0 的 SSL 证书中没有私钥

ssl - 将 .pem 转换为 .crt 和 .key

ssl - keytool 错误 : java. lang.Exception:回复中的公钥和 keystore 不匹配

java - 从 Apache Http 客户端迁移到 OkHttp

java - 如何使用 g.fillRect 方法在 Java 中创建一个 Rectangle 对象

java - keytool 错误 bash : keytool: command not found

java - 如何找到丢失的证书并添加它?