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

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

注意:

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

  2. 客户提供的签名文档无法validation。

错误:

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.(DOMX509Data.java:116) at org.jcp.xml.dsig.internal.dom.DOMKeyInfo.(DOMKeyInfo.java:116) at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.(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"); } } } 

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

希望它可以帮助别人:)

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

祝大家好运。