密码学杂谈 - 上
文章目录
安全防护
最近做软件的商业license设计,又一次对密码学进行了一些学习和了解,整理形成本文的笔记。密码学比较复杂,我了解有限,所以不打算深入介绍,仅仅针对涉及的几个应用场景进行介绍。
我们使用密码学,个人认为是应对安全防护上的三个概念: 防窃听,防伪造,防篡改,这是安全防护的主要目的。
防窃听是指防止信息在传递过程中被第三方读取。明信片在邮递过程中,信息可以被任何接触到的人看到,信息就泄露了。解决这个问题,最简单的办法,加一个密封的信封。这样信息在传递过程中就是安全的,其它人看不到。
防伪造是指防止信息的来源被第三方伪造。传统的信件防伪方法有印章,比如在圣旨上盖个大印,宣布发布者的身份,避免伪传圣旨。
防篡改是指防止信息被第三方修改。传统的方法是使用蜡丸/火漆来包装信息,完整的蜡丸/火漆表示信息未被修改。篡改信息的知名故事有“传位于四(十四)阿哥”的康熙遗旨事件。
安全防护的防泄露,防伪造,防篡改在不同的场景中有不同的需求,可以单独应用也可以结合使用。
网络中防窃听的方法是发送方把原文信息进行数字加密,传输密文,接收方只有使用秘钥才可以解开,保证信息的私密性。防伪造的方法是数字签名,发送方给信息附加一个数字签名,表明信息来源的真实性。防篡改的方式是数字摘要,对信息形成一个唯一的摘要,任何微小的原文修改都会导致数字摘要变化,从而保证信息的完整性。总结如下表:
安全防护 | 目的 | 措施 |
---|---|---|
防窃听 | 信息的私密性 | 加密 |
防伪造 | 信息来源真实性 | 签名 |
防篡改 | 信息的完整性 | 摘要 |
加密和签名
加密和解密是一个对称操作,使用秘钥对原文进行加密得到密文,再使用同一秘钥对密文进行解密得到原文。
这种使用 唯一秘钥 的加密方式叫做 对称加密
。对称加密执行效率很高,但是在网络中如何安全的传输秘钥是个问题?秘钥无法安全传输,加密就达不到防护效果。
下面是使用openssl工具进行对称加密的演示:
|
|
非对称加密
可以解决秘钥传输的安全问题。在非对称加密中使用一对秘钥: 私钥+公钥。私钥发送方(通常是服务端)保存,公钥通过网络对外发布,可以有多个接收方(通常是客户端)。客户端使用公钥加密后的密文,只能够在服务端使用私钥进行解密,即使再使用公钥也无法完成密文解密。
当然也可以反过来,使用私钥“加密”信息,公钥“解密”信息。但是由于公钥有多个,任何持有公钥的客户端,都可以对信息进行解密,所以这种私钥“加密”的信息,起不到保密的作用。只可以用来验证信息来源的唯一性,这个过程通常叫做 签名 和 验签。
私钥和公钥还有一个主要特点:公钥是通过私钥生成的,通过公钥很难推断出私钥,这样由于私钥的唯一性,可以做到信息保密。
总结一下口诀: 公钥加密,私钥解密;私钥签名,公钥验签 。
同样使用openssl工具创建非对称加密的私钥:
|
|
根据私钥创建公钥:
|
|
对信息进行加密的部分过程:
|
|
在非对称加密过程中还存在2个问题:
- 私钥加密无法达到保密效果,服务端响应信息无法加密。
- 要求明文信息必须小于秘钥长度。
一种容易想到的方法是让每个客户端也生成一对私钥+公钥,这样服务端使用客户端的公钥加密响应信息。这种方法的副作用是服务端需要保存所有的客户端公钥,实现成本较高,一般非金融类业务不会这样处理。对于明文信息必须小于秘钥长度,可采用明文分段方式进行加密,这种方法的副作用是效率更低。
比较好的解决上述2个问题的方法是把对称加密和非对称加密结合起来。客户端随机生成一个对称秘钥,然后使用公钥加密秘钥,服务端收到密文信息后解密得到秘钥。服务端使用秘钥对响应信息进行对称加密,客户端使用秘钥解密信息。这样就解决了服务端响应信息的加密问题。以后客户端再发送请求信息,都可以使用这个秘钥进行对称加密,同时也解决非对称加密效率低和秘钥长度的问题。流程如下:
步骤 | 客户端 | 服务端 |
---|---|---|
1 | 生成对称秘钥 | - |
2 | 公钥加密对称秘钥 | - |
3 | - | 私钥解密获得对称秘钥 |
4 | 使用对称秘钥加密请求明文 | - |
5 | - | 使用对称秘钥解密请求密文 |
6 | - | 使用对称秘钥加密响应明文 |
7 | 使用对称秘钥解密响应明文 | - |
证书
使用对称加密+非对称加密的结合,还有秘钥伪造的安全问题。假设客户端请求A网站服务,需要先获取A网站的公钥。如果在网络传输中B网站使用自己的公钥进行伪装替换,客户端错误的把B网站的公钥当做A网站的公钥。那么客户端发送给A网站的信息就可以被B网站窃取。
解决的办法就需要使用 证书。由一个专业的安全机构,给A网站颁发一个证书。证书实际上就是把A网站的公钥使用自己的私钥包装一下。同时这个机构还会和操作系统配合,提前在操作系统中预制自己的公钥。这样通讯中获取到A站点的证书后,使用操作系统提供的安全机构公钥解密得到A站点的公钥,从而解决公钥伪造问题。以上处理方式就是https协议的安全基础。
摘要
摘要一个应用场景是公示信息的完整性。下载网站在提供软件下载的时候,一般还会提供一个数字摘要,用来防止流氓软件捆绑。比如下面pypy软件包的摘要信息:
|
|
通过特定的散列算法,对 pypy3.9-v7.3.8rc1-linux32.tar.bz2 计算得到值为 89dd0399a89a04b58c22e9b773747258807996bd5071dbf996a85bf8af432393 的摘要。下载完成后比较一下摘要就知道软件包的完整性。
下面是另外一个摘要算法md5的示例:
|
|
散列函数形成的摘要都具有下面几个特点:
- 单向 只能够从tar包得到一个摘要值,从摘要值是无法还原完整的tar包
- 结果确定 同一个算法对每个输入的计算结果是确定
- 结果定长 可以看到字符串"1"和"123456789"得到的结果长度都是一样的
- 结果分散无规律 可以看到字符串"123456780"和"123456789",仅仅变动了1个字符,摘要却变化非常大
- 效率高 工程上摘要的计算非常快速
下面是摘要算法的一些应用场景。
去重
因为摘要算法的确定性,所以可以用来进行去重。对于数据是否变更,仅仅需要比较信息的摘要指是否变动:
|
|
密码保护
系统存储用户密码时,并不记录密码本身,仅记录密码的散列值。这样只有用户自己知道密码的明文。校验密码时,只要输入的密码正确,得到的散列值一定是一样的,表示校验通过。即使系统的数据库不小心产生泄露问题,也不会导致用户的密码泄露。
很多用户习惯使用同一个密码访问所有网站,比如A网站和B网站使用同一个密码,假设网站都是明文存储用户名和密码。A网站是大站点,网络安全处理比较好。但是B网站是小站点,发送了数据库泄露。这样攻击者利用盗取数据中的用户名和密码,从而拿到用户在A网站的重要信息。
md5算中123456789的值固定是b2cfa4183267af678ea06c7407d4d6d8,所以即使使用散列存储,也可以反向推断值为b2cfa4183267af678ea06c7407d4d6d8的密码明文是123456789。这种攻击方法一般称为 彩虹表,就是利用一些常用密码的散列值进行推测密码明文。解决这个问题的方法是 加盐 。加盐是一个通俗说法,利用散列算法的分散特性,在明文中混入一个其它数据,这样得到密文就会产生大的变化。校验的时候只要保证使用相同的盐,就可以确定明文是正确。
|
|
接口签名
摘要算法还可以用来做服务之间接口的安全认证。比如某个接口的参数如下:
|
|
对接口的参数信息进行拼接,形成一个原始的字符串:
|
|
结合参数信息和秘钥形成一个摘要签名:
|
|
因为秘钥进行双方服务器存放,不进过网络传输。所以每个请求可以通过验证签名确定来源和信息的完整性。
小结
本文我们了解了密码学的一些应用场景和解决问题的目的。目的这个很重要,可以让我们知道 加密,签名,摘要 都在保护什么。加密是保护信息的私密性,签名是保护信息来源真实性,摘要是保护信息的完整性。进而可以根据自己的需求,灵活的应用,比如创建一个自己的授权证书license。
下一节我会介绍一些算法的具体实现,以及如何实现一个license。
参考链接
文章作者 shawn
上次更新 2022-02-13