应根据以下最佳做法编写对 XML 数字签名进行签名和验证的应用程序,以避免拒绝服务攻击、数据丢失和泄露私人信息。 以下列表提供一般指导;但是,鼓励开发人员执行特定于其应用程序的其他安全分析,并查看 W3C 发布的最新数字签名最佳做法。
- 验证签名密钥 的信任
- 首先验证签名密钥并验证 SignedInfo,然后验证引用
- 使用所需的最小规范化算法集和转换
- 确保目标 URI 指向预期范围内的目标
- 验证应用程序使用的数据是否由签名
- 遵循最佳加密做法
验证签名密钥的信任
通过验证签名消息中包含的相应 X.509 证书(和证书链),确保签名密钥受信任。 或者,可以采用带外方式建立对签名密钥的信任,例如管理员配置一组受信任的密钥,或者通过安全通道查询受信任服务的应用程序。
首先验证签名密钥并验证 SignedInfo,然后验证引用
验证引用之前,验证签名密钥的信任以及 SignedInfo 元素的完整性。 同样,应用程序应在解析 清单 元素中包含的引用之前验证 清单 元素。 引用 元素允许指定目标 URI、转换和规范化算法。 如果未验证,这些字段可能用于创建拒绝服务、数据丢失或其他攻击。
使用所需的最小规范化算法集和转换
不应在未经身份验证的元素(如 KeyInfo)中使用 XSLT 和 XPATH。 如果应用程序需要使用 XPath,请限制只允许使用上级或自轴的 XPATH 表达式集,并且不计算元素的字符串值。 默认情况下,CryptXML 支持一组有限的规范化算法(请参阅 XML 数字签名加密算法中支持的 URI)。 开发人员可以实现其他转换或规范化算法,以便在其应用程序中使用。 但是,使用复杂的算法可以拒绝服务攻击或破坏签名的否认性特征。 如果应用程序需要转换,请将每个引用指定的转换数限制为应用程序所需的最高数目。 这种做法可基于过度使用转换来缓解拒绝服务攻击。
确保目标 URI 指向预期范围内的目标
应用程序应将目标 URI 限制为应用程序所需的最小范围。 例如,URI 可能预期指向同一文档、特定目标目录中的文件或特定 DNS 域中的网络位置的目标。 攻击者将 URI 设置为指向预期域外部可能会导致应用程序检索恶意内容、发送恶意 HTTP 请求(可能包含查询字符串),或导致应用程序向恶意服务器进行身份验证。
验证应用程序使用的数据是否由签名验证
如果应用程序验证签名密钥和 SignedInfo 和 引用 元素,但应用程序使用签名未引用的重要数据,则签名不提供有意义的保护。 签名的语义含义可能因签名在文档中的位置而异。 建议应用程序检查文档中签名的位置。 此外,请检查引用的数据和元素名称的位置,以缓解替换和包装攻击。
遵循最佳加密做法
随着发现新的攻击,加密算法会随着时间推移变得较弱,并且越来越多的计算能力可用。 不要将加密算法标识符或密钥大小硬编码到应用程序中。 有关最佳加密做法的更完整列表,请参阅迈克尔·霍华德和史蒂夫·利普纳,“SDL 最低加密标准”,安全开发生命周期(华盛顿雷德蒙德:Microsoft出版社,2006年),251-258。
可以在 W3C 网站上找到其他最佳做法:https://www.w3.org。
注意
某些语言和国家或地区可能无法使用这些资源。