2015-07-07 26 views
10

Durante l'analisi della firma viene visualizzato l'errore indicato di seguito. Qualcuno ha idea del perché l'errore sta mostrando?Impossibile analizzare il certificato: java.io.IOException: input vuoto X509Certificate

Nota che:

  1. Utilizzando lo stesso certificato ho firmato il mio XML e verificato che sta funzionando bene. Ciò significa che non vi è alcun problema con il certificato.

  2. Il cliente ha firmato un documento non in grado di convalidare.

Errori:

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) 

Aggiungendo il codice qui per riferimento

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

Grazie per aver risposto, Sì, ho aggiunto il codice in questione. Il suo fallimento quando accade unmarshal solo per il client firmato xml.Ma se io uso qualsiasi file xml senza segno con lo stesso certificato, fare firmare e convalidare sta dando l'errore di cui sopra. – Sam

+0

sguardo [qui] [1] [1]: http://stackoverflow.com/questions/10594000/when-i-try-to-convert-a-string-with-certificate-exception- is-raised Penso che risolverà il tuo problema. –

+0

1.Grazie per rispondere ma è correlato alla connessione SSL di cui non ho bisogno, 2. Si tratta di una modifica dei commenti precedente "Ma se utilizzo un file xml senza segno con lo stesso certificato, firmi e convalidi che funziona". problema di errore di battitura. – Sam

risposta

2

Dopo aver attraversato così tanti blog non serviva a niente in quanto tale. Infine abbiamo confermato il modo in cui il client sta eseguendo la sua crittografia e ha utilizzato gli stessi giare usati per la nostra verifica. Non sono sicuro che questa sia la risposta corretta o meno, ma può aiutare qualcuno che sta cercando di risolvere il problema. Potrebbe darti qualche indizio se non riesci a risolvere l'errore precedente dopo aver attraversato molti siti. Quindi prova a usare gli stessi jar usati per la crittografia client e ottieni la chiave privata compatibile per la tua chiave pubblica e aggiungi al file pk12. Converti pk12 in jks che puoi usare anche per la crittografia e la verifica che ha risolto il nostro problema. qualche processo troppo

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

bocca al lupo ragazzi.

8

È passato un po 'di tempo da questo post, ma sono venuto qui cercando questo problema. Nel mio caso, la chiave era che il certificato era in Base64-String.getBytes [] invece di un DECODED-Base64-String.getBytes [].

Spero che aiuti qualcuno :)

+0

Ciao, puoi chiarire questo un po 'di più? – Gobliins

+1

Sì, certo! Il problema nel mio caso era che stavo cercando di analizzare un X509Certificato da una stringa che non era un certificato X509. Era una stringa Base64 che contiene i dati del certificato quindi, per analizzarlo, ho dovuto decodificare la stringa in precedenza e quindi analizzarla su X509. – israelC