2017-06-08 10 views
1

署名とSunMSCAPIプロバイダとWindowsキーストアにスマートカードを使用しています。次のコードを使用して確認しながら、次のように私はxmlファイルを歌っていますし、それが完璧に働いていると証明書はまた、KeyInfoの中xmlファイルに埋め込まれ、embadesed x509 certyificateを持つxades4j検証の問題

private Document signXMLData(Document doc) { 
     try { 
      XadesSigningProfile p; 
      p = new XadesBesSigningProfile(keyingDataProvider).withSignaturePropertiesProvider(new SignaturePropertiesProvider() { 
       @Override 
       public void provideProperties(SignaturePropertiesCollector signedPropsCol) { 
        signedPropsCol.setSignerRole(new SignerRoleProperty(SignerRole)); 
        signedPropsCol.setSignatureProductionPlace(new SignatureProductionPlaceProperty(City, State, PostalCode, Country)); 
        signedPropsCol.setSigningTime(new SigningTimeProperty()); 
       } 
      }); 
      XadesSigner signer = p.newSigner(); 
      Element elemToSign = doc.getDocumentElement(); 
      new Enveloped(signer).sign(elemToSign); 
      Log.LogOperation("XML signing completed successfully."); 
     } catch (Exception ex) { 
      Log.LogException(ex); 
      doc = null; 
     } 
     return doc; 
    } 

しかし、私の問題があるxades4j 1.3.2バージョンを使用して 私は

コード、次のエラーを取得しています

public boolean VerifyXMLSign(String data) throws ParserConfigurationException, SAXException, IOException, TransformerConfigurationException, TransformerException, Exception { 
     InputSource isIn = new InputSource(); 
     isIn.setCharacterStream(new StringReader(data)); 

     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     dbf.setNamespaceAware(true); 
     Document doc = dbf.newDocumentBuilder().parse(isIn); 
     //Document doc = dbf.newDocumentBuilder().parse(new FileInputStream("c:/xml.xml")); 
     DOMHelper.useIdAsXmlId(doc.getDocumentElement()); 

     KeyStore ks = KeyStore.getInstance("Windows-ROOT", "SunMSCAPI"); 
     ks.load(null, null); 

     X509Certificate x509Certificate = null; 
     PublicKey key = null; 
     DOMValidateContext valContext = new DOMValidateContext(new X509KeySelector(ks), getSigElement(doc)); 
     XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM"); 
     fac.newDigestMethod(DigestMethod.SHA256, null); 
     XMLSignature signature = fac.unmarshalXMLSignature(valContext); 
     KeyInfo keyInfo = signature.getKeyInfo(); 
     Iterator hKeyInfo = keyInfo.getContent().iterator(); 
     while (hKeyInfo.hasNext()) { 
      XMLStructure hX509Data = (XMLStructure) hKeyInfo.next(); 
      if (!(hX509Data instanceof X509Data)) { 
       continue; 
      } 
      X509Data x509Data = (X509Data) hX509Data; 
      Iterator hX509Certificate = x509Data.getContent().iterator(); 
      while (hX509Certificate.hasNext()) { 
       Object oX509Certificate = hX509Certificate.next(); 
       if (!(oX509Certificate instanceof X509Certificate)) { 
        continue; 
       } 
       x509Certificate = ((X509Certificate) oX509Certificate); 
       key = x509Certificate.getPublicKey(); 
      } 
     } 

     //FileSystemDirectoryCertStore certStore = createDirectoryCertStore("my"); 
     CertificateFactory cf = CertificateFactory.getInstance("X509"); 
     ks.setCertificateEntry("df", x509Certificate); 

     CertificateValidationProvider validationProviderMySigs = new PKIXCertificateValidationProvider(ks, false, null);//certStore.getStore()); 
     XadesVerificationProfile instance = new XadesVerificationProfile(validationProviderMySigs); 
     XadesVerifier verifier = instance.newVerifier(); 
     XAdESVerificationResult r = verifier.verify(getSigElement(doc), null); 

     System.out.println(r.getSignatureForm()); 
     System.out.println(r.getSignatureAlgorithmUri()); 
     System.out.println(r.getSignedDataObjects().size()); 
     System.out.println(r.getQualifyingProperties().all().size()); 
     return false; 
    } 

エラー

Log Date Time:- 2017/06/08 14:38:01 
xades4j.utils.XadesProfileResolutionException: com.google.inject.internal.ComputationException: java.lang.SecurityException: class "org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter"'s signer information does not match signer information of other classes in the same package 
    at xades4j.utils.XadesProfileCore.getInstance(XadesProfileCore.java:223) 
    at xades4j.verification.XadesVerificationProfile.newVerifier(XadesVerificationProfile.java:147) 
    at slr.DigitalVerification.VerifyXMLSign(DigitalVerification.java:163) 
    at slr.Handlers$OpenEVerifierHandler.handle(Handlers.java:186) 
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77) 
    at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83) 
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:80) 
    at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:677) 
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77) 
    at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647) 
    at sun.net.httpserver.ServerImpl$DefaultExecutor.execute(ServerImpl.java:158) 
    at sun.net.httpserver.ServerImpl$Dispatcher.handle(ServerImpl.java:433) 
    at sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:398) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: com.google.inject.internal.ComputationException: .......... 

https://github.com/luisgoncalves/xades4j/issues/37で提案されている方法を試しましたが、同じエラーが発生しました。

私は間違っていることをお勧めします。

答えて

2

エラーから、あなたが「SunMSCAPI」からKeyStoreを作成しX509Certificateが弾むの城であるように思わXML署名、上で使用されるプロバイダによって作成されたためか、セキュリティプロバイダをアップミキシングに関連する何かです。

とにかく、署名証明書がに含まれているので、XMLを解析してそれを探している必要はありませんxades4jの目的は、そのことからあなたを抽象化することです。 xades4jは、すべての証明書をKeyInfoに集め、署名証明書の検証時にチェーンを構築するために使用します(この場合は1つしかない可能性があります)。

すべての中間証明書とあなたの歌の証明書を検証するために必要なルート証明書がのWindows-ROOT上またはKeyInfo内のいずれかであれば、あなただけの信頼されたルートKeyStoreを作成し、そのままPKIXCertificateValidationProviderにそれを渡す必要があります。追加の証明書を含める必要がある場合は、コンストラクタのCertStoreパラメータを使用できます。

要約すると、必要なコードは最初と最後です。次のようなもの:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setNamespaceAware(true); 
Document doc = dbf.newDocumentBuilder().parse(isIn); 
DOMHelper.useIdAsXmlId(doc.getDocumentElement()); 

KeyStore ks = KeyStore.getInstance("Windows-ROOT", "SunMSCAPI"); 
ks.load(null, null); 
CertificateValidationProvider validationProviderMySigs = new PKIXCertificateValidationProvider(ks, false, null); 
XadesVerificationProfile instance = new XadesVerificationProfile(validationProviderMySigs); 
XadesVerifier verifier = instance.newVerifier(); 
XAdESVerificationResult r = verifier.verify(getSigElement(doc), null); 
+0

貴重なご意見ありがとうございます。上記のすべての可能性を試しました。 BC州によってX509証明書が作成されます。私はキーストア値BKS、JKSと私の質問のコードを使用してインポートされた証明書を試してみました。しかし、すべての場合に同じエラーがXadesVerifier verifier = instance.newVerifier();という行に表示されます。上記のコードも試しましたが、同じエラーが発生します。他の回避策はありますか? – Matt

+0

'KeyStore.getInstance()'呼び出しでプロバイダを指定しないとどうなりますか? – lgoncalves

+0

KeyStore.DefaultProvider()で同じエラーが発生している場合は、 getinstanceはいくらかの価値を期待しています。 – Matt