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簽名和加密更安全地交換數據

 

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