包络签名到底有什么变化?

时间:2014-07-25 17:14:32

标签: xml digital-signature

如果我想用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>

在这两种情况下都会生成相同的输出,这样我们就可以验证签名数据是否真实。

我仍然遇到服务器问题,说我的签名无效,有人可以确认我是否正确地进行了转换吗?

非常感谢

此致

2 个答案:

答案 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()(这只是上下文)。