我需要在Java中签署一个XML文件,它需要包含3个Reference
个
虽然其中2个有效(预期摘要==实际摘要),但其中一个无效
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
&#34; SignedProperties&#34;和它的孩子
正如你可以看到&#34; QualifyingProperties&#34; Element
定义了一个名称空间(xmlns="http://uri.etsi.org/01903/v1.3.2#"
),我想这就是问题所在:
看了我发现的日志之后,&#34; Pre-Digest&#34;价值看起来像:
<SignedProperties xmlns="http://uri.etsi.org/01903/v1.3.2#" Id="SignedProperties_1">
<SignedSignatureProperties>
<SigningTime>2014-11-27T13:49:36</SigningTime>
</SignedSignatureProperties>
</SignedProperties>
而#34; SignedProperties&#34;真实文件中的Element
不包含命名空间,但它的父包含。{
我发现,实际的摘要与&#34; Pre-Digest&#34;的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
。
我的问题是,如何解决问题,即如何防止将命名空间添加到&#34; SignedProperties&#34; Element
,在计算摘要之前?
如果您需要任何其他信息,请发表评论,我对这个主题很新,所以我不确定哪些信息是相关的,哪些不相关。
非常感谢!
编辑:在玩了一下之后,在我看来,&#34;实际摘要&#34;是消化,验证器计算,而预期消化&#34;是&#34; DigestValue&#34;中的摘要。 Element
。
这意味着,我的文件中的摘要值与引用的filepart的SHA-256匹配,但验证器由于某种原因计算了父类名称空间的摘要。
所以我想我需要的是在我的摘要计算中包含parent名称空间。
编辑:我继续玩arround,现在我不仅有验证器的Pre-Digest值,还有我的&#34; digest计算&#34;。
那个给了我:
<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#"
。
我如何加入?
答案 0 :(得分:1)
我担心你无法阻止添加名称空间 - 它会在规范化过程中被添加。 This当我遇到相同的问题时,有人帮助了我;)
答案 1 :(得分:0)
经过几次尝试后,我终于找到了实际问题,以及解决方案:
正如我在问题中已经说明的那样,摘要计算没有使用父类名称空间,定义为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
的namespace-uri,因为Attribute
是名称空间,所以它是XML-Namespaces的URI。
第二个参数是属性名称,因为它不应该有任何praefix,它只是“xmlns”
第三个参数是实际的attibute-value,它是我想要“注册”的命名空间-uri
Element eQualifyingProperties
是“SignedProperties”Element
的父级。
将命名空间注册为真实命名空间(而不是属性)后,定义的Transform
Transform sigPropTransform = fac.newTransform(CanonicalizationMethod.EXCLUSIVE, (ExcC14NParameterSpec)null);
将其包含在摘要计算中。
我在this answer上找到了这个解决方案。