ONVIF专题--Xml-Signature

1 签名类型

  • 包封式:签名封装在被签名数据中,一起发往接收端
  • 分离式:签名和被签名数据分离发送的

2 XML的数字签名格式

<Signature>

  <SignedInfo>

    <CanonicalizationMethod/>  规范化方法,用于去除空格和其他格式

    <SignatureMethod/>

    (<Reference (URI)?>

    (<Transforms/>)?

    <DigestMethod/> 

    <DigestValue/>

    </Reference>)+

  </SignedInfo>

  <SignatureValue/>

  (<KeyInfo/>)?

  (<Object ID?/>)*

</Signature>

3 式例--包封式签名示例

需要被签名的XML文档如下:

<license>

  <test>hello world</test>

</license>

签名后的XML:

<license>

  <test>hello world</test>

  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <!--[s01]-->

    <ds:SignedInfo> <!--[s02]-->

      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2006/12/xml-c14n11" /> <!--[s03]-->

      <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /> <!-- [s04]-->

      <ds:Reference URI="" Id=""> <!--[s05]-->

        <ds:Transforms> <!--[s06]-->

          <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> <!--[s07]-->

          <ds:Transform Algorithm="http://www.w3.org/2006/12/xml-c14n11" />

        </ds:Transforms> <!--[s08]-->

        <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> <!--[s09]-->

        <ds:DigestValue> <!--[s10] -->

          d+F/TTTxoF2Fk/knoTwHLqC7gqa+ETnTn84sNwx4c0Y=

        </ds:DigestValue>

      </ds:Reference> <!--[s11]-->

    </ds:SignedInfo> <!--[s12]-->

    <ds:SignatureValue>KdSti.....6OA==</ds:SignatureValue> <!--[s13]-->

    <ds:KeyInfo> <!--[s14]-->

      <ds:KeyValue> <!--[s15a]-->

        <ds:RSAKeyValue> <!--[a15b]-->

          <ds:Modulus>nM95A0J.....+GQ==</ds:Modulus> <!--[a15c]-->

          <ds:Exponent>AQAB</ds:Exponent> <!--[a15d]-->

        </ds:RSAKeyValue> <!--[a15e]-->

      </ds:KeyValue> <!--[a15f]-->

    </ds:KeyInfo> <!--[a16]-->

  </ds:Signature> <!--[a17]-->

</license>

SignedInfo
[s02-12]该元素的子元素包含有关所签名的内容以及签名方式的所有信息。签名算法实际上应用于该元素及其所有子元素以生成签名。

CanonicalizationMethod
[s03]该元素指定了用于SignedInfo元素以便将XML规范化的规范化(C14N)算法。(常常也是transform算法的一部分)

SignatureMethod
[s04]该元素指定了该签名的签名算法。这里的签名算法是带有RSA的SHA-256。

Reference

  • [s05-11]这些元素指定了将要签名的数据,并指定哈希运算之前应当如何对该数据进行处理。URI属性(它表示统一资源标识符)标识要签名的数据,而Transforms元素(稍后描述)指定在进行哈希运算之前如何处理数据。在该示例中,我们将使用特殊的URI——空字符串,它表明签名与被签名在同一个包中(包封式)。Id属性用来标记xml包中需要局部签名的数据Id.
  • XML签名标准对Reference数据使用间接签名机制。该标准不是对Reference中的所有数据进行统一的哈希运算然后加密哈希值,而是使用由Reference的DigestMethod元素所指定的算法对每个Reference的数据进行哈希运算,然后将哈希值存储到Reference的DigestValue元素中。接下来,对SignedInfo元素和它的所有子元素(包括Reference元素)进行哈希运算;哈希值被加密以生成签名。因此,您实际上是对Reference元素中所引用数据的哈希的哈希进行签名,但是该方案仍然可以保护数据的完整性。
  • [s05]Reference的这个可选 URI 属性标识要签名的数据对象。 在一个 Signature 中,至多可以对一个Reference省略该属性。(为了确保明确地匹配引用和对象, 要强加这个限制。)
  • [s06-08]该标识与transforms一起是签名者提供的描述, 其内容有关它们如何获得已编摘形式的已签名数据对象(即,已编摘的内容)。验证者还可能以另一种方法获得已编摘的内容,只要摘要验证这种方法。

Transforms
[s06-08]每个Reference元素都可以具有零个或更多个为它指定的转换。这些转换按照它们在XML中列出的顺序应用于该Reference的数据。转换使您可以在对Reference的数据进行哈希运算之前对该数据进行筛选或修改。在该示例中,我们将使用包封式签名转换,该转换选择了包含文档中除Signature元素以外的所有XML(排除Signature元素)。我们必须从将被签名的数据中移除Signature元素,否则,当我们存储签名值时,可能会修改我们尝试签名的数据。

DigestMethod
[s09-10]DigestMethod 是在应用 Transforms(如果已经指定它)之后对数据应用以产生 DigestValue 的算法。DigestValue 存储产生的哈希值。

SignatureValue
[s13]该元素包含通过签名SignedInfo元素及其所有子元素而计算得到的签名值

KeyInfo
[s14-16]KeyInfo表示用于验证签名的密钥(公钥)。标识机制可以包括证书、密钥名称和密钥协议算法。KeyInfo是可选的有两个原因:首先,签名者可能不希望向所有文档处理方披露任何密钥信息。其次,该信息在应用程序上下文中可能是已知的,并且不需要明确表示。 由于KeyInfo在SignedInfo之外,所以如果签名者希望将密钥信息与签名绑定,那么Reference可以容易地将KeyInfo作为签名的一部分标识并将其包括在内(在Reference增加被签名数据源)。

3.1 签名过程

  • 首先,对于签名中的每个Reference元素:
    • 按照转换在Transforms元素下面出现的顺序,将Transform元素中指定的每个转换算法应用于Reference的数据。 
    • 使用Reference的DigestMethod元素所指定的哈希算法对经过转换的数据进行哈希运算。 
    • 在Reference的DigestValue元素中存储产生的哈希值。
  • 然后,使用在签名的CanonicalizationMethod元素中指定的算法规范化SignedInfo元素及其子元素。
  • 最后,使用在签名的SignatureMethod元素中指定的算法对SignedInfo元素及其子元素进行签名。签名值被存储在SignatureValue元素中。

3.2 验证过程

签名验证是刚刚描述的过程的逆过程。

  • 首先,必须使用CanonicalizationMethod元素中指定的C14N算法规范化SignedInfo元素及其子元素。
  • 然后,必须针对SignedInfo元素及其子元素验证SignatureValue元素中存储的签名值。
    • 最后,对于签名中的每个Reference元素:
    • 按照转换在Transforms元素下面出现的顺序,将Reference的Transform元素中指定的每个转换算法应用于Reference的数据。 
    • 使用Reference的DigestMethod元素所指定的哈希算法对Reference的经过转换的数据进行哈希运算。 
    • 将计算得到的哈希值与DigestValue元素中存储的值进行比较。

 

个人理解

从上面有关xml签名的规范看(被签名数据-[transform/Canonicalization/Digest]->DigestValue-[Canonicalization/Signature]->SignatureValue),确实可以做到万无一失保证数据不被篡改,但是每一条报文都这样是否消耗太多资源

 

参考:

[1] 什么是XML?什么是XML数字签名?

[2] 通过XML签名和加密更安全地交换数据

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章