签名和加密顺序
先签名后加密,接收方只能知道消息是由签名者发送的,但消息的创建者并不一定是签名者。如果消息在中途被截获,替换成截获者的签名,存在中间人攻击的风险。如果使用先签名后加密的方案,则能够规避这种风险。
先签名后加密的通信过程一般如下:
- 使用 的私钥 对明文消息 进行签名 ;
- 然后使用 的公钥 对消息 进行加密称为密文 ;
- 密文 传输到 处, 通过 对消息解密回 ;
- 然后 使用 对消息 进行校验;

上述过程安全的保证来自于, 和 的私钥是各自持有,不为第三方所知。 间可以约定一个固定的字符串, 使用 的私钥对该字符串进行加密,然后将该字符串的密文附加在消息中,这串密文的作用类似于签名。 收到该密文后,可以使用 的公钥解密,校验该字符串是否为约定的字符串,这便可以校验签名是否为 的。
一般来说,我们说加密能保证消息的机密性,签名能防止篡改,但是如果顺序不对还是会产生攻击的漏洞。
看这种情况:

从上图可知,先签名后加密的话,存在中间人攻击的风险。
虽然存在风险,但如果这种风险能够被消解,那么先加密后签名的方案也是可行的。
中间人攻击能够成功的前提是:
- 接收方 从签名的内容中找到对应的公钥 来验证签名;
- 接收方 只用公钥签名认证消息的发送方;
这两个前提都要满足才有构成中间人攻击的条件,所以能否使用先加密后签名的方案也需要看具体的场景。如果 使用固定的公钥来验证签名,比如通信双方约定一个可信的公证人,使用其签名保证消息无篡改;如果消息中带有用户身份的属性,比如用户的 ID 等,那么消息解密后 通过验证 的用户属性,那也能确认消息是 发出的(这时,这个用户属性充当了前面签名的角色,其实还是一种先签名后加密)。