署名を解析するときに、以下のエラーが表示されます。エラーが表示される理由は誰にもわかりますか?
ご了承ください:
同じ証明書を使用して独自のXMLに署名し、どちらが正常に機能しているかを検証しました。つまり、証明書に問題はありません。
クライアントが検証できない署名されたドキュメントを提供しました。
エラー:
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");
}
}
}
この投稿からしばらく経ちましたが、この問題を探してここに来ました。私の場合、鍵は証明書がDECODED-Base64-String.getBytes []ではなくBase64-String.getBytes []にあることでした。
それが誰かを助けることを願っています:)
非常に多くのブログを通過した後、何もそのように役立ちませんでした。最後に、クライアントの暗号化方法を確認し、検証に使用したのと同じjarを使用しました。これが正しい答えであるかどうかはわかりませんが、この問題を解決しようと懸命に努力している人を助けるかもしれません。多くのサイトを通過した後、上記のエラーを解決できない場合、いくつかの手がかりを得ることができます。したがって、クライアント暗号化に使用したのと同じjarを使用して、公開キーと互換性のある秘密キーを取得し、pk12ファイルに追加してみてください。 pk12をjksに変換します。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
がんばれ。