2015-07-07 47 views
10

Otrzymuję błąd podany poniżej podczas analizowania podpisu. Ktoś ma pomysł, dlaczego pokazuje błąd?Nie można przeanalizować certyfikatu: java.io.IOException: pusty wpis X509Certyfikat

zauważyć, że:

  1. Używanie tego samego certyfikatu zapisałam moje własne XML i weryfikacji, który pracuje bez zarzutu. Oznacza to, że nie ma problemu z certyfikatem.

  2. Klient, któremu dostarczono podpisany dokument, nie może potwierdzić.

Błędy:

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) 

Dodawanie kod tutaj odniesienie

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

Dzięki za odpowiedź, Tak, dodałem sam kod. Jego niepowodzenie, gdy niemiłosierne dzieje się tylko dla klienta podpisanego xml.Ale jeśli korzystam z dowolnego niepodpisanego pliku xml z tym samym certyfikatem, zrób i zatwierdź to daje powyższy błąd. – Sam

+0

wygląd [o] [1] [1]: http://stackoverflow.com/questions/10594000/when-i-try-to-convert-a-string-with-certificate-exception- jest podniesiony Myślę, że to rozwiąże twój problem. –

+0

1.Dziękuję za odpowiedź, ale jest to związane z połączeniem SSL, którego nie potrzebuję, 2. To jest wcześniejsza edycja komentarza "Ale jeśli użyję dowolnego niepodpisanego pliku xml z tym samym certyfikatem, zrób podpis i sprawdzenie, czy działa." problem literowy. – Sam

Odpowiedz

2

Po przejściu przez tak wielu blogach nic nie pomagało jako takie. Ostatecznie potwierdziliśmy, że klient robi szyfrowanie i używa tych samych słoików używanych do naszej weryfikacji. Nie jestem pewien, czy jest to poprawna odpowiedź, czy nie, ale może pomóc komuś, kto stara się rozwiązać ten problem. Może to dać ci wskazówkę, jeśli nie uda Ci się rozwiązać powyższego błędu po przejściu przez wiele stron. Spróbuj użyć tych samych słoików, które są używane do szyfrowania klienta i uzyskaj kompatybilny klucz prywatny dla twojego klucza publicznego i dodaj do pliku pk12. Konwertuj pk12 na jks, które możesz wykorzystać do szyfrowania i weryfikacji, które rozwiązały nasz problem. Pewien proces też

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

Powodzenia chłopaków.

8

Minęło trochę czasu od tego wpisu, ale przyjechałem tutaj, szukając tego problemu. W moim przypadku klucz był taki, że certyfikat był w Base64-String.getBytes [] zamiast DECODED-Base64-String.getBytes [].

Mam nadzieję, że komuś pomogę :)

+0

Witam, czy możesz wyjaśnić to nieco więcej? – Gobliins

+1

Tak, jasne! Problem w moim przypadku polegał na tym, że próbowałem przeanalizować certyfikat X509 z Stringa, że ​​nie był to certyfikat X509. Był to ciąg Base64, który zawiera dane certyfikatu, więc aby go przetworzyć, musiałem go wcześniej zdekodować, a następnie przeanalizować go na X509. – israelC