web-dev-qa-db-fra.com

Impossible d'analyser le certificat: Java.io.IOException: entrée vide X509Certificate

J'obtiens l'erreur indiquée ci-dessous lors de l'analyse de la signature. Quelqu'un a une idée pourquoi l'erreur s'affiche?

Notez que:

  1. En utilisant le même certificat, j'ai signé mon propre XML et vérifié ce qui fonctionne bien. Cela signifie qu'il n'y a aucun problème avec le certificat.

  2. Le client a fourni un document signé non valide.

Les erreurs:

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)

Ajout du code ici pour référence

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");
        }

    }

}
16
Sam

Cela fait un moment depuis ce post mais je suis venu ici à la recherche de ce problème. Dans mon cas, la clé était que le certificat se trouvait dans un Base64-String.getBytes [] au lieu d'un DECODED-Base64-String.getBytes [].

J'espère que cela aide quelqu'un :)

20
israelC

Après avoir parcouru tant de blogs, rien n'a aidé en tant que tel. Enfin, nous avons confirmé la façon dont le client effectue son cryptage et avons utilisé les mêmes pots utilisés pour notre vérification. Je ne sais pas si c'est la bonne réponse ou non, mais cela peut aider quelqu'un qui s'efforce de résoudre ce problème. Cela peut vous donner un indice si vous ne pouvez pas résoudre l'erreur ci-dessus après avoir parcouru de nombreux sites. Essayez donc d'utiliser les mêmes jars que ceux utilisés pour le chiffrement du client et obtenez la clé privée compatible pour votre clé publique et ajoutez-la au fichier pk12. Convertissez pk12 en jks que vous pouvez également utiliser pour le cryptage et la vérification, ce qui a résolu notre problème. Certains processus aussi

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

Bonne chance les gars.

1
Sam