ブラジルの政府機関に署名したXMLファイルを送信する必要があります。 。問題は私のJavaコードによって計算されたダイジェストは、(Java XML Digital Signature APIを使用してXMLSECのような他のツールで生成されたものとは異なるということであるJava XMLデジタル署名APIを使用したxml署名のダイジェスト値が正しくない
ここで私はいくつかのXMLノードのXML署名を生成するために使用するコードです:
private synchronized void sign(XmlObject obj) throws Exception {
initKeystore();
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
List<Transform> transformList = new ArrayList<Transform>();
Transform envelopedTransform = fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
Transform c14NTransform = fac.newTransform("http://www.w3.org/TR/2001/REC-xml-c14n-20010315",
(TransformParameterSpec) null);
transformList.add(envelopedTransform);
transformList.add(c14NTransform);
Reference ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)), null,
null);
SignedInfo si = fac.newSignedInfo(
fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null),
fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref));
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream(System.getProperty("javax.net.ssl.keyStore")),
System.getProperty("javax.net.ssl.keyStorePassword").toCharArray());
KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("entry",
new KeyStore.PasswordProtection(System.getProperty("javax.net.ssl.keyStorePassword").toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
// Create the KeyInfo containing the X509Data.
KeyInfoFactory kif = fac.getKeyInfoFactory();
X509Data xd = kif.newX509Data(Collections.singletonList(cert));
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
// Instantiate the document to be signed.
Element el = (Element) obj.getDomNode().getFirstChild();
String id = el.getAttribute("Id");
DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), el);
// Create the XMLSignature, but don't sign it yet.
XMLSignature signature = fac.newXMLSignature(si, ki);
// Marshal, generate, and sign the enveloped signature.
signature.sign(dsc);
}
同じ秘密鍵を使用して
$ xmlsec1 --verify consulta.xml
func=xmlSecOpenSSLEvpDigestVerify:file=digests.c:line=229:obj=sha1:subj=unknown:error=12:invalid data:data and digest do not match
FAIL
しかし、私は非常に同じファイル(consult.xml)に署名しようとした場合xmlsecと(:
私はxmlsecで生成されたXMLを検証しようとすると、私は次のエラーを取得します)、そのエラーは離れ:
consulta.xml:
<DigestValue>Ajn+tfX7JQc0HPNJ8KbTy7Q2f8I=</DigestValue>
...
<SignatureValue>Q1Ys0Rtj8yL2SA2NaQWQPtmNuHKK8q2anPiyLWlH7mOIjwOs0GEcD0WLUM/BZU0Q
T0kSbDTuJeTR2Ec9wu+hqXXbJ76FpX9/IyHrdyx2hLg0VhB5RRCdyBEuGlmnsFDf
XCyBotP+ZyEzolbTCN9TjCUnXNDWtFP1YapMxAIA0sth0lTpYgGJd8CSvFlHdFj+
ourf8ZGiDmSTkVkKnqDsj8O0ZLmbZfJpH2CBKicX+Ct7MUz2sqVli4XAHs6WXX+E
HJpbOKthS3WCcpG3Kw4K50yIYGTkTbWCYFxOVsMfiVy4W/Qz15Vxb8chD8LM58Ep
m/szmvnTAESxv/piDr7hyw==</SignatureValue>
xmlsec1 --sign --output doc-signed.xml --privkey-pem cert.pem consulta.xml
consult.xml及び(xmlsecによって生成された)DOC-signed.xml違いはSignatureValueとDigestValueタグの内容は
DOC-signed.xml:
<DigestValue>w6xElXJrZw3G86OsNkWav+pcKJo=</DigestValue>
...
<SignatureValue>YmUsnlnAY9uLhlfVBLhB8K8ArxMOkOKZJoQ6zgz55ggU6vJCO9+HWJCKQJp6Rvn/w5PCAFY0KJRb
r6/WhHML0Z+Q6TSuIL8OTvJ3iPoROAK6uy07YAflKOUklqk4uxgfMkR+hWMCyfITJVCVZo/MXmPy
g7YwmztoSlGH+p6+ND5n2u47Y2k6SpIvw3CUxwAVQkD0Hsj3G58cbUbrFCoyPVGOe4zJ9c1HPsMW
KzBEFe3QETzPJ8I1B7EEVi5oDvzXE2rMTH4K7zvNGnXpBNGwnSjEOticlqKVP5wyUD7CPwgF1Wgy
Z0njvlaW3K8YmAY8fc70v/+wSO6Fu+0zj18Xeg==</SignatureValue>
彼らは同じだから、私はどちらかのファイルの残りの部分を投稿しないだろうし、この投稿をもっと冗長にするでしょう。
このXMLファイルを受け取るWebアプリケーションは.NETアプリケーションで、Javaコード(xmlsecとよく似ています)とは異なる署名ダイジェストを計算します。何か案は?
申し訳ありませんが、ダイジェストハッシュアルゴリズムはSHA1ですか?それは他のものでも構いませんし、署名はRSA_SHA1(あなたのコードを読んでいるので)でもかまいません。 – esej
それは私がJava APIにすることです。私が気づいたことの一つは、xmlsドキュメントをファイルに保存し、そのファイルを読み込んで私が読んだものに署名すると、ダイジェストが正しく計算されるということです。ですから、空白が何らかの形でJavaまたはXMLSEC側で検討されている可能性があります。 xmlに一度だけ署名する必要があれば、それは私の問題を解決するでしょう。問題は私が少なくとも2回それをする必要があるということです... – Andre
あなたは '\ n'を騙しましたか? –