摘要:很多安全规范及安全文章中都提到一条规则:先加密后签名是不安全的,应当先签名后加密。这条规则背后的原理是什么?先加密后签名一定不安全吗?本文为您一一解答。
先签名后加密是指先对消息进行签名,然后对消息的签名值和消息一起进行加密。如果采用先加密后签名的方式,接收方只能知道该消息是由签名者发送过来的,但并不能确定签名者是否是该消息的创建者。比如在发送一个认证凭据时采用先加密后签名的方式,消息在发送过程中就有可能被第三方截获并将认证凭据密文的签名值修改为自己的签名,然后发送给接收方。第三方就有可能在不需知道认证凭据的情况下通过这种方式来通过认证获取权限。
采用先签名后加密方式可以避免这类问题的发生,因为只有在知道消息明文的情况下才能对其进行签名。
虽然不同的规范描述有差异,但核心观点都是“先签名后加密”。但是这条规范的适用场景是什么呢,“先加密后签名”一定不安全吗?需要深挖一下。
如果使用“先加密后签名”,则消息发送方Alice和消息接收方Bob的处理过程如下图:
Alice发送的明文消息先经过Alice私钥签名,再将消息明文和消息签名一起使用Bob的公钥加密,密文经过网络传输到Bob。因为Bob使用私钥解密还原出消息明文和签名,而私钥只有Bob持有,这能保证消息明文不会泄露给第三方Eve,然后Bob使用Alice的公钥验证消息明文和签名是否一致,因为Alice的签名只有Alice的公钥才能验证,这能保证消息一定来自Alice,不可抵赖,且没有被第三方Mallory篡改。在拿不到消息明文的情况下,无法计算出消息签名,而还原消息明文又必须使用Bob的私钥,这样就能防止网络传输过程中的中间人进行篡改攻击。
假如“先加密后签名”,会存在什么样的攻击风险呢,先看下“先加密后签名”的处理流程:
消息明文使用Bob的公钥加密,不可能泄露给第三方,签名也有了,可以防篡改,不仔细看的话,似乎没什么问题。继续看下面这张图:
如果存在一个中间人Mallory可以拦截Alice和Bob的消息,在不篡改消息明文和密文的情况下,使用Mallory的私钥对消息密文进行签名,并替换Alice原始的签名,最后篡改后的消息传输给接收方Bob,Bob仍然可以成功解密明文,同时用Mallory的公钥成功验证签名,最终这条消息会被Bob认为是Mallory发送的合法消息。
“先加密后签名”一定不安全吗
从上面的演示来看,“先加密后签名”似乎一定不安全,是这样吗?中间人Mallory针对“先加密后签名”进行替换签名攻击得手的前提条件:
1、 接收方Bob根据签名内容中的证书ID找到对应的Mallory公钥来验证签名。
2、 接收方Bob仅使用公钥验签来识别发送方的身份。
只要打破上面的任意一个前提,“先加密后签名”也是安全的:
1、 Bob使用固定的公钥来验证签名,而不是根据签名内容来找对应公钥,或者不使用多个公钥尝试验签。即Mallory替换签名后,Bob仍然用Alice的公钥验证签名,肯定能发现请求被篡改。
2、 Bob使用公钥+应用层属性一起识别发送方的身份,假设Alice在消息明文中携带自己的用户ID,Bob验证公钥和用户ID是否匹配,即使Mallory替换签名也无法攻击。
所以“先加密后签名”是不是安全,还要看业务应用是怎么设计的,不能绝对的认定为不安全。
本文分享自华为云社区《“先签名后加密”的思考》,原文作者:卡农。