我需要用Java签署一个XML,它需要包含3个Reference。
虽然其中两个是有效的(预期摘要==实际摘要),一个是无效的。
XML的相关部分如下所示:
<QualifyingProperties xmlns="http://uri.etsi.org/01903/v1.3.2#" Target="Signature1">
<SignedProperties Id="SignedProperties_1">
<SignedSignatureProperties>
<SigningTime>2014-11-27T13:49:36</SigningTime>
</SignedSignatureProperties>
</SignedProperties>
</QualifyingProperties>Reference只引用Element "SignedProperties“及其子程序。
如您所见,"QualifyingProperties“Element定义了一个名称空间(xmlns="http://uri.etsi.org/01903/v1.3.2#"),我猜这就是问题所在:
在查看了我发现的日志之后,“预摘要”值如下所示:
<SignedProperties xmlns="http://uri.etsi.org/01903/v1.3.2#" Id="SignedProperties_1">
<SignedSignatureProperties>
<SigningTime>2014-11-27T13:49:36</SigningTime>
</SignedSignatureProperties>
</SignedProperties>虽然实际文件中的"SignedProperties“Element不包含名称空间,但其父文件包含。
我发现,实际摘要与“预摘要”值的SHA-256匹配,而预期摘要与实际文件的SHA-256匹配(没有命名空间)。
Reference是用以下代码创建的:
Reference sigPropRef = fac.newReference("#SignedProperties_1", fac.newDigestMethod(DigestMethod.SHA256, null),
Collections.singletonList(sigPropTransform), "http://uri.etsi.org/01903#SignedProperties", "reference-signedpropeties"
);其中sigPropTransform是一个CanonicalizationMethod.EXCLUSIVE Transform。
我的问题是,在计算摘要之前,如何解决这个问题,即如何防止将名称空间添加到"SignedProperties“Element中?
如果你需要任何其他信息,请留下评论,我对这个主题非常陌生,所以我不确定哪些信息是相关的,哪些信息不相关。
非常感谢!
编辑:在我看来,“实际摘要”是摘要,验证器计算出来的,而“预期摘要”是"DigestValue“Element中的摘要。
这意味着,我的文件中的摘要值与引用的文件部分的SHA-256匹配,但是验证器出于某种原因计算摘要WITh (父名称空间)。
因此,我想我需要的是在我的摘要计算中包括父名称空间。
编辑:,我继续四处游玩,现在我不仅有了验证器的预摘要值,而且还有我的“摘要计算”。
这个给了我:
<SignedProperties Id="SignedProperties_1"><SignedSignatureProperties><SigningTime>2014-11-27T15:51:26</SigningTime></SignedSignatureProperties></SignedProperties> 当我给它以下Transform时:
Transform sigPropTransform = fac.newTransform(CanonicalizationMethod.EXCLUSIVE, (ExcC14NParameterSpec)null); 和:
<SignedProperties xmlns:ds="some-url" xmlns:msg="some-other-url" Id="SignedProperties_1"><SignedSignatureProperties><SigningTime>2014-11-27T15:52:49</SigningTime></SignedSignatureProperties></SignedProperties>当我不给它任何Transform。
名称空间xmlns="http://uri.etsi.org/01903/v1.3.2#"从未包括在内。
我该怎么把它包括进去?
发布于 2014-11-27 15:50:12
经过几次尝试,我终于找到了实际问题,以及解决办法:
正如我在问题中所指出的,摘要计算没有使用父名称空间(定义为xmlns="http://uri.etsi.org/01903/v1.3.2#" )。
这是因为我从未将它“注册”为名称空间,但我只将它作为一个普通的Attribute添加。要“注册”我需要调用setAttributeNS而不是setAttribute的命名空间。
然后,代码看起来类似于:
Element eQualifyingProperties= doc.createElement("QualifyingProperties");
eQualifyingProperties.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "http://uri.etsi.org/01903/v1.3.2#"); 第一个参数是Attribute的命名空间- URI,因为Attribute是一个名称空间,所以它是XML空间的URI。
第二个参数是属性名称,因为它不应该有任何praefix,所以它只是"xmlns“。
第三个参数是实际的attibute-值,它是我想要“注册”的命名空间-uri。
Element eQualifyingProperties是"SignedProperties“Element的父级。
将名称空间注册为实际名称空间(而不是属性)之后,定义的Transform
Transform sigPropTransform = fac.newTransform(CanonicalizationMethod.EXCLUSIVE, (ExcC14NParameterSpec)null); 将其包括在摘要计算中。
我在SO上的这个答案中找到了这个解决方案。
发布于 2014-11-27 14:30:53
恐怕您无法阻止添加命名空间--它是在canonicalizaton期间添加的。当我有相同的问题时,这一帮了我;)
https://stackoverflow.com/questions/27171847
复制相似问题