Xades4j: хранилище ключей не может быть инициализировано - PullRequest
0 голосов
/ 28 января 2019

Я пытаюсь импортировать сертификат, который я недавно установил в Windows, в Java для использования с xades4j.К сожалению, я довольно нов, когда дело доходит до сертификатов, ключей и всего такого.

Однако каждый раз, когда я запускаю программу, я получаю следующую ошибку:

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

Мне нужноподписать документ XML в формате XaDeS-BES.Я импортировал ключ (или сертификат?) С диска, и он находится в сертификатах доверенных корневых центров сертификации Windows.Я экспортировал его в корень диска C из диспетчера сертификатов Windows (certmgr.msc).

Я нашел одну запись на этом сайте , в которой упоминалось о следующих попытках инициализации хранилища ключей:

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

К сожалению, изменений не было.

Код, который я использовал, основан на примере 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);
}

Спасибо за любую помощь.

1 Ответ

0 голосов
/ 30 января 2019

Для выполнения операции подписи вам нужен ключ / сертификат пара , а именно контейнер PKCS12.В Windows эта пара обычно представляет собой файл .pfx или .p12.Я не уверен, в чем проблема, но вот некоторые соображения, которые могут вам помочь:

  • Сертификат, который используется для подписи, обычно является «личным» сертификатом, а не корневым сертификатом доверенного органа..
  • Корневой сертификат - это сертификат, принадлежащий объекту, который обычно выдает сертификаты другим субъектам.
  • Часть процесса проверки сертификата заключается в создании цепочки доверия от сертификата субъекта дов корневой сертификат.В Windows доверенные корневые сертификаты находятся в указанном вами магазине: «Доверенные корневые центры сертификации Windows».Ваш сертификат подписи, вероятно, не должен быть там.
  • Поскольку вы выполняете операцию подписи (для подписи BES) и используете FileSystemKeyStoreKeyingDataProvider, цепочка доверия на самом деле не так важна.Это становится актуальным, когда вы проверяете подпись.
  • Из вашего кода кажется, что у вас есть файл только для сертификата (.cer).Я не знаю, как вы получили сертификат в первую очередь, но он должен был быть предоставлен вместе с ключом, вероятно, в комплекте с .pfx файлом, защищенным паролем.
  • При создании FileSystemKeyStoreKeyingDataProvider вы должны передать файл PKCS12 (например, .pfx)
  • Если у вас установлен сертификат в каком-то другом хранилище Windows, попробуйте экспортировать его с ключом (если это возможно; зависит от того, как он был импортирован)в первую очередь).

Надеюсь, это поможет.

...