gpt4 book ai didi

java - 使用 Java XML 数字签名 API 的 xml 签名的摘要值错误

转载 作者:IT老高 更新时间:2023-10-28 20:23:56 25 4
gpt4 key购买 nike

我需要将签名的 XML 文件发送给巴西的政府机构。问题是我的 Java 代码计算的摘要(使用 Java XML Digital Signature API 与使用另一种工具(如 XMLSEC)生成的摘要不同。

这是我用来为某些 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);

}

如果我尝试使用 xmlsec 验证生成的 XML,我会收到以下错误:

$ 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

但如果我尝试使用 xmlsec(使用相同的私钥)签署同一个文件 (consult.xml),该错误就会消失:

xmlsec1 --sign --output doc-signed.xml --privkey-pem cert.pem consulta.xml

consult.xml 和 doc-signed.xml(由 xmlsec 生成)的区别在于 SignatureValue 和 DigestValue 标签的内容:

consulta.xml:

<DigestValue>Ajn+tfX7JQc0HPNJ8KbTy7Q2f8I=</DigestValue>
...
<SignatureValue>Q1Ys0Rtj8yL2SA2NaQWQPtmNuHKK8q2anPiyLWlH7mOIjwOs0GEcD0WLUM/BZU0Q
T0kSbDTuJeTR2Ec9wu+hqXXbJ76FpX9/IyHrdyx2hLg0VhB5RRCdyBEuGlmnsFDf
XCyBotP+ZyEzolbTCN9TjCUnXNDWtFP1YapMxAIA0sth0lTpYgGJd8CSvFlHdFj+
ourf8ZGiDmSTkVkKnqDsj8O0ZLmbZfJpH2CBKicX+Ct7MUz2sqVli4XAHs6WXX+E
HJpbOKthS3WCcpG3Kw4K50yIYGTkTbWCYFxOVsMfiVy4W/Qz15Vxb8chD8LM58Ep
m/szmvnTAESxv/piDr7hyw==</SignatureValue>

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 所做的)。有什么想法吗?

最佳答案

如果现在回答还不算太晚:

您在代码中创建了 2 个转换(envelopeTransform 和 c14NTransform),但不要使用它们。

您使用一个新的 Transform.ENVELOPED 创建引用。 http://www.w3.org/TR/2001/REC-xml-c14n-20010315 (C14N) 变换未应用。

现在,我不确定 XML 安全标准说这种情况下的行为应该是什么。也许其他工具也会自动应用 C14N 变换。

我确定如果您不指定任何变换,JDK 将至少应用 C14N 变换。

基本上更改 fac.newReference("", ...) 并将 transformList 传递给它,而不是 Collections.singletonList()。

关于java - 使用 Java XML 数字签名 API 的 xml 签名的摘要值错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10404434/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com