2015-07-07 12 views
10

Ich erhalte den unten angegebenen Fehler beim Parsen der Signatur. Hat jemand eine Idee warum der Fehler angezeigt wird?Zertifikat konnte nicht analysiert werden: java.io.IOException: Leere Eingabe X509Certificate

Beachten Sie, dass:

  1. das gleiche Zertifikat verwenden ich mein eigenes XML signiert und verifiziert, die fein arbeitet. Das bedeutet, dass es kein Problem mit dem Zertifikat gibt.

  2. Das vom Kunden bereitgestellte signierte Dokument kann nicht validiert werden.

Fehler:

Exception in thread "main" javax.xml.crypto.MarshalException: Cannot create X509Certificate 
at org.jcp.xml.dsig.internal.dom.DOMX509Data.unmarshalX509Certificate(DOMX509Data.java:225) 
at org.jcp.xml.dsig.internal.dom.DOMX509Data.<init>(DOMX509Data.java:116) 
at org.jcp.xml.dsig.internal.dom.DOMKeyInfo.<init>(DOMKeyInfo.java:116) 
at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.<init>(DOMXMLSignature.java:150) 
at org.jcp.xml.dsig.internal.dom.DOMXMLSignatureFactory.unmarshal(DOMXMLSignatureFactory.java:173) 
at org.jcp.xml.dsig.internal.dom.DOMXMLSignatureFactory.unmarshalXMLSignature(DOMXMLSignatureFactory.java:137) 
at com.signing.ValidateSignedXML.main(ValidateSignedXML.java:126) 
Caused by: java.security.cert.CertificateException: Could not parse certificate: java.io.IOException: Empty input 
at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:104) 
at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339) 
at org.jcp.xml.dsig.internal.dom.DOMX509Data.unmarshalX509Certificate(DOMX509Data.java:223) 
... 6 more 
Caused by: java.io.IOException: Empty input 
at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:101) 

den Code hier als Referenz Hinzufügen

package com.signing; 

import java.io.FileInputStream; 
import java.security.KeyStore; 
import java.security.cert.X509Certificate; 
import java.util.Iterator; 

import javax.xml.crypto.dsig.Reference; 
import javax.xml.crypto.dsig.XMLSignature; 
import javax.xml.crypto.dsig.XMLSignatureFactory; 
import javax.xml.crypto.dsig.dom.DOMValidateContext; 
import javax.xml.parsers.DocumentBuilderFactory; 

import org.w3c.dom.Document; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 

public class ValidateSignedXML { 

    /** 
    * @param args 
    * @throws Exception 
    */ 
/** 
    * @param args 
    * @throws Exception 
    */ 
    public static void main(String[] args) throws Exception { 
     // TODO Auto-generated method stub 

     // Load the KeyStore and get the signing key and certificate. 
     KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 
     ks.load(new FileInputStream("C:\\Program Files\\Java\\jre1.8.0_31\\bin\\newstore8.jks"), "changeit7".toCharArray()); 


     KeyStore.PrivateKeyEntry keyEntry = 
      (KeyStore.PrivateKeyEntry) ks.getEntry 
       ("newkey8", new KeyStore.PasswordProtection("changeit7".toCharArray())); 
     X509Certificate cert = (X509Certificate) keyEntry.getCertificate(); 
     XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM"); 


     //Load the signed document. 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     dbf.setNamespaceAware(true); 
     Document doc = dbf.newDocumentBuilder().parse 
      (new FileInputStream("C:\\src\\com\\signing\\signed.xml")); 


     // Find Signature element. 
     NodeList nl = 
      doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); 
     if (nl.getLength() == 0) { 
      throw new Exception("Cannot find Signature element"); 
     }else{ 
      /*System.out.println("---- Start of Print Tag ----\n"); 
      for(int k=0;k<nl.getLength();k++){ 
       printTags((Node)nl.item(k)); 
      } 
      System.out.println("---- End of Print Tag ----\n");*/ 
     } 

     // Create a DOMValidateContext and specify a KeySelector 
     // and document context. 
     DOMValidateContext valContext = new DOMValidateContext 
      (new X509KeySelector(), nl.item(0)); 

     // Unmarshal the XMLSignature. 
     XMLSignature signatures = fac.unmarshalXMLSignature(valContext); 

     // Validate the XMLSignature. 
     boolean coreValidity = signatures.validate(valContext); 

     System.out.println("Signature Validate :"+coreValidity); 

     // Check core validation status. 
     if (coreValidity == false) { 
      String validateError; 
      validateError = "Signature core validation status:false"; 
      boolean sv = signatures.getSignatureValue().validate(valContext); 
      validateError = validateError + " | Signature validation status:" + sv; 
      if (sv == false || true) { 
       validateError = validateError + " | References: "; 
       // Check the validation status of each Reference. 
       Iterator g = signatures.getSignedInfo().getReferences().iterator(); 
       for (int j = 0; g.hasNext(); j++) { 

        Reference r = (Reference) g.next(); 
        boolean refValid = r.validate(valContext); 
        validateError = validateError + "{ref[" + r.getURI() + "] validity status: " + refValid + "}"; 
       } 
      } 
      throw new Exception(validateError); 
     } else { 
      System.out.println("Signature passed core validation"); 
     } 

    } 

} 
+0

Danke für die Antwort, Ja, ich habe den Code in Frage selbst hinzugefügt. Es scheitert, wenn unmarshal geschieht nur für Client-signierten xml.Aber wenn ich eine nicht signierte xml-Datei mit dem gleichen Zertifikat verwenden, signieren und validieren es gibt über den Fehler. – Sam

+0

Look [hier] [1] [1]: http://stackoverflow.com/questions/10594000/when-i-try-to-convert-a-string-with-certificate-exception- is-raised Ich denke, es wird Ihr Problem lösen. –

+0

1.Thanks für die Antwort, aber es ist mit SSL-Verbindung verbunden, die ich nicht brauche, 2.Dies ist früher Kommentar bearbeiten "Aber wenn ich irgendeine unsigned XML-Datei mit dem gleichen Zertifikat verwenden, signieren und validieren es funktioniert." Tippfehler. – Sam

Antwort

2

Nachdem man durch so viele Blogs geht nichts als solche geholfen. Schließlich haben wir bestätigt, dass der Client seine Verschlüsselung durchführt und dieselben für unsere Verifizierung verwendeten Jars verwendet. Ich bin mir nicht sicher, ob dies die richtige Antwort ist oder nicht, aber kann jemandem helfen, der sich bemüht, dieses Problem zu lösen. Es kann Ihnen einen Hinweis geben, wenn Sie nicht in der Lage sind, den oben genannten Fehler zu beheben, nachdem Sie viele Websites durchlaufen haben. Versuchen Sie also, die gleichen Dateien zu verwenden, die für die Clientverschlüsselung verwendet werden, und erhalten Sie den kompatiblen privaten Schlüssel für Ihren öffentlichen Schlüssel und fügen Sie ihn zur PK12-Datei hinzu. Konvertieren Sie pk12 in jks, das Sie auch für die Verschlüsselung und Überprüfung verwenden können, wodurch unser Problem gelöst wurde. Einige Prozess zu

#**Create PKCS12 keystore from private key and public certificate.** 
openssl pkcs12 -export -name myservercert -in selfsigned.crt -inkey server.key -out keystore.p12 
#**Convert PKCS12 keystore into a JKS keystore** 
keytool -importkeystore -destkeystore mykeystore.jks -srckeystore keystore.p12 -srcstoretype pkcs12 -alias myservercer 

Viel Glück Jungs.

8

Es ist eine Weile her seit dieser Post, aber ich kam hierher, um nach diesem Problem zu suchen. In meinem Fall war der Schlüssel, dass das Zertifikat in einem Base64-String.getBytes [] statt eines DECODED-Base64-String.getBytes [] war.

Hoffe es hilft jemandem :)

+0

Hallo, können Sie das ein bisschen mehr klären? – Gobliins

+1

Ja, sicher! Das Problem in meinem Fall war, dass ich versuchte, ein X509Certificate von einem String zu analysieren, dass es kein X509Certificate war. Es war eine Base64-Zeichenfolge, die die Daten des Zertifikats enthält. Um sie analysieren zu können, musste ich die Zeichenfolge zuvor dekodieren und sie dann zu einem X509 analysieren. – israelC

Verwandte Themen