XML数字签名-Signature语法和签名算法

一段Demo:

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
        <!-- 规范化的算法 -->
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
        <!-- 签名算法:rsa-sha1 -->
        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
        <!-- 确定待签名的引用资源 -->
        <ds:Reference URI="">
            <!-- 转换算法 -->
            <ds:Transforms>
                <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
            </ds:Transforms>
            <!-- 消息摘要的算法,比如:SHA1 -->
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <!-- 消息摘要 -->
            <ds:DigestValue>{{DigestValue}}</ds:DigestValue>
        </ds:Reference>
    </ds:SignedInfo>
    <!--  签名内容 -->
    <ds:SignatureValue>{{SignatureValue}}</ds:SignatureValue>
    <!-- KeyInfo 元素可选,表明签名的公钥信息 -->
    <ds:KeyInfo>
        <ds:KeyName>{{KeyName}}</ds:KeyName>
        <ds:X509Data>
            <ds:X509Certificate>{{X509Certificate}}</ds:X509Certificate>
        </ds:X509Data>
    </ds:KeyInfo>
</ds:Signature>

签名算法

XML-signature 中的签名算法就是对XML文档树进行签名,说明如下:
1、确认签名内容,通过 URL 将这些内容表示为引用资源,用 Reference 标识。对于断言信息来说,其 URI 是saml:Assertion的 ID
2、对待签名的数据进行转化处理,包括执行编码规则、规范化算法等, Transform 指定了转化的算法
3、对整个断言进行消息摘要,DigestMethod 指定了消息摘要算法,消息摘要的结果保存在 DigestValue 元素中
4、构造包含 ReferenceSignedInfo 元素
5、CanonicalizationMethod 元素指定了规范化的算法,如果不对其进行规范化处理,验证 xml 签名时可能因为xml 结构表示不同而失败
6、计算 SignedInfo 的摘要,使用 SignatureMethod 声明的签名算法,并对其进行签名,结果保存到 SignatureValue 元素中
7、KeyInfo 元素可选,表明签名的公钥信息

举例封内签名(包封式签名)

使用签名被封装在被签名XML中的方式

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

<license>
  <test>hello world</test>
</license>

签名后的XML:

<license>
    <test>hello world</test>
    [s01]<ds:Signature
        xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        [s02]<ds:SignedInfo>
            [s03]<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
            [s04]<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
            [s05]<ds:Reference URI="">
                [s06]<ds:Transforms>
                    [s07]<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                [s08]</ds:Transforms>
                [s09]<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                [s10]<ds:DigestValue>d+F/TTTxoF2Fk/knoTwHLqC7gqa+ETnTn84sNwx4c0Y=</ds:DigestValue>
            [s11]</ds:Reference>
        [s12]</ds:SignedInfo>
        [s13]<ds:SignatureValue>KdSti.....6OA==</ds:SignatureValue>
        [s14]<ds:KeyInfo>
            [s15a]<ds:KeyValue>
                [a15b]<ds:RSAKeyValue>
                    [a15c]<ds:Modulus>nM95A0J.....+GQ==</ds:Modulus>
                    [a15d]<ds:Exponent>AQAB</ds:Exponent>
                [a15e]</ds:RSAKeyValue>
            [a15f]</ds:KeyValue>
        [a16]</ds:KeyInfo>
    [a17]</ds:Signature>
</license>

元素说明

SignedInfo

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

CanonicalizationMethod

[s03]该元素指定了用于SignedInfo元素以便将XML规范化的规范化(C14N)算法。

SignatureMethod

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

Reference

[s05-11]这些元素指定了将要签名的数据以及在哈希运算之前应当如何对该数据进行处理。URI属性(它表示统一资源标识符)标识要签名的数据,而Transforms元素(稍后描述)指定在进行哈希运算之前如何处理数据。在该示例中,我们将使用特殊的URI——空字符串,它指定包含签名的文档是要包含在签名中的数据。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元素,否则,当我们存储签名值时,可能会修改我们尝试签名的数据。

DigestMethod

[s09-10]DigestMethod 是在应用 Transforms(如果已经指定它)之后对数据应用以产生 DigestValue 的算法。DigestValue 的签名是将资源内容与签名者密钥绑定的机制。

SignatureValue

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

KeyInfo

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

版权声明:本文为CSDN博主「yaoel」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/persistvonyao/article/details/80446497

最后修改:2022 年 02 月 20 日 05 : 26 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论