关于 XML 签名

Adobe AIR 1.5 和更高版本

XML 签名是使用 XML 语法表示的数字签名。XML 签名中的数据可用于验证签名的信息自签名以来是否未更改过。此外,当签名证书由受信任证书颁发机构颁发之后,可以通过公钥基础结构验证签名者的身份。

XML 签名可应用于任何类型的数字数据(以二进制或 XML 格式)。XML 签名一般用于如下目的:

  • 检查外部或下载的资源是否被修改

  • 验证消息是否来自已知来源

  • 验证应用程序许可证或订阅权限

支持的 XML 签名语法

AIR 支持以下来自针对 XML 签名语法和处理的 W3C 建议的元素:

  • 所有核心签名语法元素(W3C 建议文档的第 4 节)— 但不完全支持 KeyInfo 元素

  • KeyInfo 元素必须仅包含 X509Data 元素

  • X509Data 元素必须仅包含 X509Certificate 元素

  • SHA256 摘要方法

  • RSA-SHA1 (PKCS1) 签名算法

  • “不带注释的规范化 XML”规范化方法和转换

  • 封装的签名转换

  • 时间戳

以下文档阐释典型的 XML 签名(为简化本例,已删除大多数加密数据):

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> 
    <SignedInfo> 
        <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> 
        <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> 
        <Reference URI="URI_to_signed_data"> 
            <Transforms> 
                <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>            </Transforms> 
            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> 
            <DigestValue>uoo...vY=</DigestValue> 
        </Reference> 
    </SignedInfo> 
    <SignatureValue>Ked...w==</SignatureValue> 
    <KeyInfo> 
        <X509Data> 
            <X509Certificate>i7d...w==</X509Certificate> 
        </X509Data> 
    </KeyInfo> 
</Signature>

签名的重要元素有:

  • SignedInfo — 包含对签名的数据和在签名时计算的摘要值的引用。签名的数据本身可能包含在与 XML 签名相同的文档中,也可能在外部。

  • SignatureValue — 包含使用签名者的私钥加密的 SignedInfo 元素的摘要。

  • KeyInfo — 包含签名证书,以及建立信任链所需的任何其他证书。注意,尽管从技术角度来看 KeyInfo 元素是可选的,但如果不包括该元素,AIR 就无法验证签名。

有三种常规类型的 XML 签名:

  • Enveloped — 此签名插入要签名的 XML 数据的内部。

  • Enveloping — 签名的 XML 数据包含在 Signature 元素的 Object 元素中。

  • Detached — 签名的数据位于 XML 签名的外部。签名的数据可能在外部文件中。另一种情况是,该数据可能位于与签名相同的 XML 文档中,只不过不是 Signature 元素的父元素或子元素。

XML 签名使用 URI 引用签名的数据。签名和验证应用程序必须使用相同的约定解析这些 URI。当使用 XMLSignatureValidator 类时,必须提供 IURIDereferencer 接口的实现。此实现负责解析 URI 并作为 ByteArray 对象返回签名的数据。使用在签名中生成摘要的同一算法对返回的 ByteArray 对象生成摘要。

证书和信任

证书由公钥、标识信息以及属于颁发证书的认证机构的一个或多个证书构成。

共有两种方法在证书中建立信任。可以通过直接从签名者获取证书的副本来建立信任,例如在物理媒体上,或者通过安全数字传输,如 SSL 事务。还可以依赖证书颁发机构来确定签名证书是否可信。

若要依赖证书颁发机构,签名证书必须由验证签名的计算机上信任的颁发机构颁发。大多数操作系统制造商都将许多证书颁发机构的根证书放置在操作系统的信任存储区中。 用户还可以向存储区添加或从中删除证书。

即使证书是由受信任证书颁发机构颁发的,仍须确定该证书是否属于您信任的人。在许多使用案例中,此决定传递到最终用户。例如,当安装 AIR 应用程序时,AIR 安装程序在要求用户确认是否要安装应用程序时,将显示发行者证书的标识信息。在其他情况下,可能需要将公钥或其他证书信息与可接受的密钥列表进行比较。(此列表必须是安全的,它或者由自己签名,或者存储在 AIR 加密的本地存储区中,以便列表本身不会被篡改。)

注: 虽然可以选择信任没有独立验证的签名证书(如“自签名”证书),但这样将不会通过验证签名获得任何保证。不知道谁创建了签名,保证签名不被篡改几乎没有意义。签名可能是对有效签名的伪造。

证书过期和吊销

所有证书过期。证书还可以由颁发证书的认证机构吊销,例如,与证书关联的私钥泄露或被盗。如果使用过期或吊销的证书进行了签名,则会将该签名报告为无效签名,除非将时间戳包括在签名中。如果存在时间戳,则只要证书在签名时是有效的,XMLSignatureValidator 类将验证该签名。

时间戳是来自时间戳服务的签名数字消息,用于证明该数据在特定的时间和日期经过签名。 时间戳由时间戳颁发机构颁发,并由时间戳颁发机构自己的证书进行签名。嵌入时间戳的时间戳颁发机构证书必须在当前计算机上受信任,时间戳才会被认为是有效的。XMLSignatureValidator 不提供用于指定在验证时间戳时使用其他证书的 API。