无法解析证书:java.io.IOException:空输入X509Certificate

时间:2015-07-07 17:30:12

标签: java rsa x509certificate x509 signing

解析签名时,我收到下面给出的错误。有谁知道错误显示的原因?

请注意:

  1. 使用相同的证书我签署了自己的XML并验证了哪个工作正常。这意味着证书没有问题。

  2. 客户提供的签名文件无法验证。

  3. 错误:

    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)
    

    在此处添加代码以供参考

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

3 个答案:

答案 0 :(得分:17)

这篇帖子已经有一段时间了,但我来到这里寻找这个问题。在我的例子中,关键是证书是在Base64-String.getBytes []而不是DECODED-Base64-String.getBytes []。

希望它可以帮助某人:)

答案 1 :(得分:2)

经历了这么多博客之后没有任何帮助。最后,我们确认了客户端进行加密的方式,并使用了用于验证的相同jar。我不确定这是否是正确的答案,但可能会帮助那些努力解决这个问题的人。 如果在通过许多站点后无法解决上述错误,它可能会给你一些线索。 因此,尝试使用用于客户端加密的相同jar并获取公钥的兼容私钥并添加到pk12文件。将pk12转换为可用于加密和验证的jks,这解决了我们的问题。 一些过程也是

#**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
祝你好运。

答案 2 :(得分:-1)

错误就像在证书集中没有 BEGIN END 标签一样简单。

-----BEGIN CERTIFICATE-----
your cert data here
-----END CERTIFICATE-----