我正在研究将应用程序从SHA1升级为默认的PKCS#7 SignedData摘要算法,以更强的摘要(如SHA256),以保留不支持SHA1以外的摘要算法的签名验证程序的向后兼容性。我想检查一下我对PKCS#7格式和可用选项的理解。
我想要做的是使用SHA1和SHA256(或更一般地说,一组摘要算法)消化消息内容,以便较旧的应用程序可以继续通过SHA1进行验证,升级后的应用程序可以通过SHA256开始验证(更一般地说,提供了最强的摘要),忽略了较弱的算法。 [如果有更好的方法,请告诉我。]
似乎在PKCS#7标准中,提供多个摘要的唯一方法是提供多个SignerInfos,每个摘要算法一个。不幸的是,这似乎会导致安全性的网络减少,因为攻击者能够使用最弱的摘要算法剥离除SignerInfo之外的所有算法,而单独的摘要算法仍将形成有效的签名。这种理解是否正确?
如果是这样,我的想法是在SignerInfo的authenticatedAttributes字段中使用自定义属性为其他摘要算法提供额外的消息摘要(将SHA1保留为“默认”算法以实现向后兼容)。由于此字段被认证为单个块,因此可以防止上述攻击。这似乎是一种可行的方法吗?有没有办法在不超出PKCS标准的情况下完成这个或类似的东西?
答案 0 :(得分:8)
是的,你是对的,在当前的CMS RFC中说明了消息摘要属性
signerInfo中的SignedAttributes 必须只包含message-digest属性的一个实例。 同样,AuthenticatedData中的AuthAttributes必须包括 只有一个message-digest属性的实例。
因此,使用标准签名属性提供多个消息摘要值的唯一方法是提供几个signedInfos。
是的,任何安全系统都与其最薄弱的环节一样强大,所以从理论上讲,如果你仍然接受SHA-1,你就不会通过添加带有SHA-256的SignedInfo获得任何东西 - 正如你所说的那样,更强的签名可以随时被剥夺了。
使用自定义属性的方案有点难以破解 - 但仍然存在可以攻击的SHA-1哈希值。它不再像剥离属性一样简单 - 因为签名覆盖了它。但是:
还有摘要算法用于消化签名属性,该属性用作最终签名值的基础。你打算在那里使用什么? SHA-256还是SHA-1?如果它是SHA-1,那么你将处于和以前一样的情况:
如果我可以为SHA-1产生冲突,那么我将剥离你的自定义SHA-256属性并伪造SHA-1属性,使得签名的最终SHA-1摘要再次加起来。这表明如果签名摘要算法也是SHA-256,那么安全性只会增加,但我猜这不是一个选项,因为你想保持向后兼容。
在您的情况下,我建议您始终使用SHA-1,但将符合RFC 3161的时间戳应用于您的签名作为无符号属性。这些时间戳实际上是他们自己的签名。好处是您可以在其中使用SHA-256进行消息打印,并且时间戳服务器通常使用您提供的相同摘要算法应用其签名。然后拒绝任何不包含此类时间戳或仅包含时间戳的签名,其中消息压缩/签名摘要算法弱于SHA-256。
此解决方案的好处是什么?您的旧应用程序应检查是否存在未签名的时间戳属性,以及是否使用了强摘要,但是否则忽略它们并继续以与之前相同的方式验证签名。另一方面,新应用程序将验证签名,但另外还验证时间戳。由于时间戳签名“覆盖”签名值,攻击者不再能够伪造签名。虽然签名使用SHA-1作为摘要值,但攻击者必须能够打破时间戳的强大摘要。
时间戳的另一个好处是,您可以将生产日期与签名相关联 - 您可以安全地声明签名是在时间戳之前生成的。因此,即使要撤销签名证书,在时间戳的帮助下,您仍然可以根据证书被撤销的时间精确地决定是拒绝还是接受签名。如果证书在时间戳之后被撤销,那么您可以接受签名(添加安全边际(也称为“宽限期”) - 如果信息发布需要一些时间),如果它在时间戳之前被撤销那么你想拒绝签名。
时间戳的最后一个好处是,如果某些算法变弱,您可以随时更新它们。例如,您可以使用最新算法每5到10年应用一个新的时间戳,并使新的时间戳覆盖所有较旧的签名(包括较旧的时间戳)。这样,弱算法就可以被更新,更强的时间戳签名所覆盖。看看CAdES(还存在RFC,但现在已经过时了),它基于CMS,并尝试应用这些策略来提供CMS签名的长期归档。