无法解析证书:java.io.IOException:空输入 X509Certificate
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31275509/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Could not parse certificate: java.io.IOException: Empty input X509Certificate
提问by Sam
I am getting the error given below when parsing the signature. Anybody has idea why the error is showing?
解析签名时出现以下错误。有人知道为什么显示错误吗?
Note that:
注意:
Using the same certificate I signed my own XML and verified which is working fine. That mean there is no issue with certificate.
Client provided signed document not able to validate.
使用相同的证书我签署了我自己的 XML 并验证哪个工作正常。这意味着证书没有问题。
客户提供的签名文件无法验证。
Errors:
错误:
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)
Adding the code here for reference
在此处添加代码以供参考
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");
}
}
}
回答by Sam
After going through so many blogs nothing helped as such. Finally we confirmed the way client is doing his encryption and used the same jars used for our verification. I am not sure if this is correct answer or not but may help somebody who is trying hard to resolve this issue. It may give you some clue if not able to resolve above error after going through many sites. So try to use same jars which used for client encryption and get the compatible private key for your public key and add to pk12 file. Convert pk12 to jks which you can use for encryption and verification too which resolved our issue. Some process too
在浏览了这么多博客之后,没有任何帮助。最后,我们确认了客户端进行加密的方式,并使用了用于我们验证的相同 jars。我不确定这是否是正确答案,但可能会帮助正在努力解决此问题的人。如果在浏览许多站点后无法解决上述错误,它可能会给您一些线索。因此,请尝试使用用于客户端加密的相同 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
Good luck guys.
祝大家好运。
回答by israelC
It's been a while since this post but I came here looking for this issue. In my case, the key was that the certificate was in a Base64-String.getBytes[] instead of a DECODED-Base64-String.getBytes[].
这篇文章已经有一段时间了,但我来这里是为了寻找这个问题。就我而言,关键是证书位于 Base64-String.getBytes[] 而不是 DECODED-Base64-String.getBytes[]。
Hope it helps someone :)
希望它可以帮助某人:)
回答by Filip Hanik Pivotal
Error can be as simple as not having the BEGINand ENDtags in your certificate set.
错误可以像证书集中没有BEGIN和END标签一样简单。
-----BEGIN CERTIFICATE-----
your cert data here
-----END CERTIFICATE-----