提问者:小点点

信封签名到底转换了什么?


如果我想使用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封装签名代码包括

<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个答案

匿名用户

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并确认文档(实践部分在学习过程中非常重要)。

匿名用户

建议使用转换XPath,但不是必需的。必需的是转换包络签名。

但是,转换包络签名必须与转换XPath具有相同的效果。

总之,

当签名在其被签名的内容中时,包络签名转换会从签名的计算中删除签名元素。

这已经回答了你的具体问题:

信封签名到底转换了什么?

即使它回答了你的问题,它也可能不会给你留下任何解决代码问题的线索(你应该在问题中提供这些线索)。当你忽略代码时,我只能与你提供的XML相关。让我们将其与上面的答案进行比较:

在您的情况下,正在签名的内容是

<getToken>
<item>
<Semilla>001520685466</Semilla>
</item>
</getToken>

然后在其中创建Signature元素:

<getToken>
<item>
<Semilla>001520685466</Semilla>
</item>
<Signature>...</Signature>
</getToken>

但是,Transform XPath要求Signature元素位于不同的XML命名空间中,这里即

<XPath xmlns:dsig="&dsig;">
   count(ancestor-or-self::dsig:Signature |
   here()/ancestor::dsig:Signature[1]) >
   count(ancestor-or-self::dsig:Signature)</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必须能够识别的信封签名