前前后后,花了2周左右的时间,学习了范学雷老师的《实用密码学》,不全是讲理论,居于牛郎织女约会时的喜鹊送信问题,怎么解决安全、准确、不被窥视等常规现代通信加密、解密问题。整体上娓娓道来,虽说对于非密码学人士来说比较深奥,但理解密码产生的场景,其中攻防策略还是非常有帮助的。
其通信需要解决的问题:
Q: 怎么证明双方身份?
A: 识别身份,确定牛郎就是牛郎(和谍战片中接头人的原理类似); 认证身份,验证牛郎就是牛郎
Q: 怎么使消息不泄漏?
A: 管理特权,授予织女看信权利;
Q: 怎么防止内容被篡改?
A: 信息保密,没有权限不能看信;
Q: 怎么确保信件能收到?
A: 信息完整,保护内容不被篡改;
Q: 怎么防止翻脸不认账?
A: 信息可用,保持信息获取能力;
对称密钥解决“机密性”
部分公开信息,告诉织女怎么解密,这部分信息包含:
- 使用两个孩子的生辰八字作为推导对称密钥的秘密;
- 使用什么密钥推导算法(PBKDF2推导算法)来从共有的秘密推导对称密钥;
- 使用什么对称密钥算法来加密、解密约会信息。
选择密码学算法,目前推荐256位安全强度是首选。牛郎发送的信息既包含私密信息,又包含公开信息,两者均不能被篡改,这种情形下我们可以选用带关联数据的的认证加密算法,也就是AEAD算法,推荐 ChaCha20/Poly1305 中备选。这类算法需要四个输入数据:
- 一个256位的对称密钥;
- 一个96位的随机数:“随机生成 0A 00 00 00 00 00 4B 00 00 00 ED”;
- 待加密数据明文,也就是私密信息;
- 关联数据,也就是公开信息。
怎么推导这个256位对称密钥呢?居于推导算法PBKDF2算法,此算法需要五个输入参数:
- 用户的口令:“生辰八字”;
- HMAC算法:“HmacSHA256”;
- 盐值,类似于我们讨论过的初始化向量:“随机选一个 3B 07 A6 CB CF 98 48 F0 68 11 28 40 E7 6F 98 66”;
- 迭代次数:“1”;
- 导出密钥长度:“256”。
怎么定义关联数据呢?其实就是通信协议。关键就是要告诉织女这封信的格式,以及怎么解密这封信件。其中,需要包含我们上述提到的算法的选择,以及对应的参数,大致地,我们可以这样写这封信:
这封信使用 ChaCha20/Poly1305 算法加密,随机数选取的是“0A 00 00 00 00 00 4B 00 00 00 ED”(十六进制表示),关联数据是本信件内容除去加密数据之外的所有数据,加密密钥是使用 PBKDF2算法推导256位的对称密钥。PBKDF2算法的用户口令,使用的男孩和女孩的生辰八字,HMAC算法使用的 HmacSHA256算法,盐值选取的是“3B 07 A6 CB CF 98 48 F0 68 11 28 40 E7 6F 98 66”(十六进制表示),迭代一次。此后为加密数据。6E 2E35 9A 25 68 F9 80 41 BA 07 28 DD 0D 69 81 ...... 5A F9 0B BF 74 A8 5B B6 B4 0B 8E ED
有了这封信,ChaCha20/Poly1305算法要使用的关联数据也就确定下来了。就是信件里,除了加密数据之外所有的数据。
AEAD算法简介
TLS协议中使用的模式最开始有ECB、CBC等,为了对消息完整性进行确认,保证消息没有被篡改,还需要一个HMAC算法,其实就是对消息进行hash,得出来的值缀在被确认消息的后边。这就有个问题,是先对明文进行HMAC,再加密;还是先加密,再对密文进行HMAC。最开始是先对明文取HMAC,再加密(RFC5246,TLS1.2);后来认为这种不安全,就先加密,再对密文取HMAC(RFC7366, encrypt-then-mac);再后来认为这样也不安全,就出现了加密和验证在同一个操作中进行,也就是AEAD(RFC5116, Authenticated Encryption with Associated Data),带附加数据的认证加密算法。
AEAD的实现步骤为:1. 通过密钥key对消息加密,通过增加随机数来保证隐私(AES256);2. 计算一个认证标签,通过该认证标签可保证一条消息中加密和未加密的部分均未被篡改。