如果我想用envoloped签名签署下一个XML代码:
<root>
<element>
<child>text node</child>
</element>
</root>
然后签名XML代码在签名的XML代码中进行,方式如下所示:
<root>
<element>
<child>text node</child>
</element><Signature xmlns="http://www.w3.org/2000/09/xmldsig#">...</Signature>
</root>
Notice: no line break nor single character is added outside Signature element since that would invalidate the signature.
XML包络的签名代码包括&lt;变换算法&gt;它规定了代码必须经受的修改,严格来说无论是在签名还是验证过程中都要进行修改。 &lt;变换算法&gt;是下一个:
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
在W3C网站(官方文档)中,将上面的表达式与下面的表达式进行比较。在这两种情况下都必须产生相同的输出。
<XPath xmlns:dsig="&dsig;">
count(ancestor-or-self::dsig:Signature |
here()/ancestor::dsig:Signature[1]) >
count(ancestor-or-self::dsig:Signature)</XPath>
参考:http://www.w3.org/TR/xmldsig-core/#sec-EnvelopedSignature
变换之前:
案例1(签署):
<root>
<element>
<child>text node</child>
</element>
</root>
案例2(签名):
<root>
<element>
<child>text node</child>
</element><Signature xmlns="http://www.w3.org/2000/09/xmldsig#">...</Signature>
</root>
转化后:
<root>
<element>
<child>text node</child>
</element>
</root>
在这两种情况下都会生成相同的输出,这样我们就可以验证签名数据是否真实。
我仍然遇到服务器问题,说我的签名无效,有人可以确认我是否正确地进行了转换吗?
非常感谢
此致
答案 0 :(得分:6)
Transform的确切功能是用它的后代擦除整个Signature元素。一个实际的例子是下一个签名数据:
<root>
<element>
<child>text node</child>
</element>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">...</Signature>
</root>
转换必须产生下一个输出:
<root>
<element>
<child>text node</child>
</element>
</root>
请注意Signature之外的每个字符都会被保留,包括每个换行符和空格键。如果我们用冒号表示空格键,我们有下一个视图:
<root>
::<element>
::::<child>text node</child>
::</element>
::
</root>
我建议访问下一个链接,我可以从中清除对此问题的所有怀疑: http://www.di-mgt.com.au/xmldsig2.html
最好的链接是它包含一个真实的签名示例,任何人都可以从中重现相同的DigestValue并确认文档(实际部分在学习过程中非常重要)。
答案 1 :(得分:2)
建议使用Transform XPath 但不是必需的。必需的是Transform Enveloped Signature 。
但是, Enveloped Signature 必须与Transform XPath 具有相同的效果。
简而言之,
当签名位于签名内容中时,Enveloped签名转换会从签名计算中删除Signature元素。
那已经回答了你的具体问题:
封装签名到底有什么变化?
即使它回答了你的问题,它仍然可能不会给你留下任何关于解决代码问题的指示(你应该在你的问题中提供)。当您离开代码时,我只能与您提供的XML相关联。让我们将其与上面的答案进行比较:
在您的情况下,正在签名的内容是
<getToken>
<item>
<Semilla>001520685466</Semilla>
</item>
</getToken>
然后在其中创建Signature
元素:
<getToken>
<item>
<Semilla>001520685466</Semilla>
</item>
<Signature>...</Signature>
</getToken>
然而,Transform XPath 要求Signature
元素位于不同的XML命名空间内,即&dsig
:
<XPath xmlns:dsig="&dsig;">
count(ancestor-or-self::dsig:Signature |
here()/ancestor::dsig:Signature[1]) >
count(ancestor-or-self::dsig:Signature)</XPath>
&dsig;
是一个XML实体,代表(在您提及的日期说明中)文本&#34; http://www.w3.org/2000/09/xmldsig#
&#34;。由于您在该XML命名空间中使用的Signature
元素不是而不是,因此它不是有效的XML签名,因此XPath转换的XPath表达式无法解决此问题。
由于必需的转换必须与推荐的XPAth转换匹配,因此您不需要在此处执行必需的操作,因为包络签名转换 T 的XPath确实如此不匹配XML文档中的任何元素。
因此,简而言之,这只是一个缺少的XML名称空间声明。
使XPath变得复杂的原因在于它涵盖了Signature
元素本身可能与另一个封装的Signature
签名的情况,以便从您要签署的XML文档中签名XPath表达式仅涉及该文档的封套签名,而不是签名作为该签名中另一个(内部)签名的信封。但是如果Xpath在一个可能是签名的信封中的上下文中也是如此:
<root>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" id="envelope">
...
<Signature>
...
</Signature>
</Signature>
</root>
对于此类封装签名,XPath必须能够识别<root>
或 <Signature xmlns="http://www.w3.org/2000/09/xmldsig#" id="envelope">
的信封签名,具体取决于here()
(这只是上下文)。