理解数字签名与证书原理
非对称加密技术
互联网行业能有今日之成就,非对称加密技术功不可没。
我们知道,网络通信数据在物理上无法避免被窃听,甚至篡改和伪造,因此必须寻求一种方法,让接收者知道数据被中间人动了手脚。传统的对称加密技术,双方约定一个相同的数(密钥),解密就是做加密的逆运算,这种方法无法有效的解决这个问题,因为必须把这个密钥藏好,不能有软件接口可以获取到,更不能通过网络明文传输,一旦中间人知道密钥,就可以随意篡改伪造通信数据,而接收方却蒙在鼓里。
魔高一尺道高一丈,研究者们搞出了非对称加密算法,非对称加密算法采用一对密钥,这对密钥分别被命名为公钥(Public Key)和私钥(Private Key),公钥加密的数据需要私钥解密,私钥加密的数据需要公钥解密,并且得知其中一个无法推算出另一个。基于这样的前提,我们可以把私钥存储在本地,公钥公开给所有人,任何人都可以用这个公钥加密数据发给我,但中间人窃听到数据也没用,因为他没有私钥,解密不出真实数据,当然我们也需要验证发送者的身份是否合法,只不过这是解密出数据之后干的事了(例如真实数据里包含用户名和密码)。
非对称加密算法使用最为广泛的是RSA,它的数学理论推荐看这篇博客 跨越千年的RSA算法 ,写得通俗易懂。我基于这位兄台的博客,用Java实现了个算法原型 简单理解RSA算法(Java原型实现)。
摘要算法
摘要算法即Hash算法(哈希算法),它可以将任意长度的二进制数据映射到一段固定长度的二进制数据,映射出的这段较小的二进制数据被称为Hash值。这个算法的特点很有意思,对原数据的一点小变动都会引起Hash值的巨大变化,而且这种算法不可逆,不能通过Hash值计算出原数据。
因为Hash值的上述特点,它经常作为消息的摘要,也称为数字指纹,要判断一个消息是否经过修改,只需要判断它的Hash值是否发生变化。
数字签名
把非对称加密算法和数字指纹相结合,就可以验证发送者的消息是否被中间人篡改,比如下载者验证网上下载的文件。具体过程是,文件发布者先为文件内容生成指纹,然后用自己的私钥对指纹进行加密,加密后的指纹就是数字签名,然后将文件数据、数字签名、公钥一起打包发布,下载者下载完成后,用发布者的公钥解密数字签名,拿到指纹,然后计算一下当前文件数据的指纹,对比一下,如果相同则说明数据未被篡改。这个过程中数字签名具有两重意义,其一是锁定了文件内容,因为文件数据一旦更改,下载者验证指纹时就对不上,攻击者也不能伪造签名,因为他没有文件发布者的私钥;其二是具有不可抵赖性,一旦验证成功,就可以证明这文件一定是公钥对应私钥的拥有者发布的,或者说是他验证过的。可见,数字签名和现实中的签名的意义是一样的。
然鹅,上面这个过程有一个很大的bug,接收者凭什么信任这个公钥,不可能在系统中预装全世界所有可信的公钥吧,很有可能攻击者替换为了自己的公钥,这样的话所有数据都不具有可信度了。
证书这个东西正是用来解决此问题的。
证书
上面说到,文件发布者简单的提供一个公钥,并不能证明自己可靠,需要提供更可靠的东西,这个玩意儿就是证书,证书里面包含使用者名称、有效期、公钥等信息,这还不够,因为这种数据攻击者也可以随便造,因此还需要证书颁发机构的名称和数字签名,这跟现实中证书要盖章是一回事。根据颁发机构名称可以在本地文件系统检索颁发机构的证书,找到之后拿到颁发机构的公钥,就可以验证这个数字签名是否是他签的。然后,颁发机构的证书还得验证可靠性,同样的,根据上一级颁发者的数字签名来验证,如此沿着证书链,自下而上逐一验证,到系统安装的根证书为止,中途验证失败则说明证书有问题。
签发证书的机构被称为CA(信任中心),CA本身也有证书,由上一级CA签发,除了Root CA,他们是自己给自己签发一个证书,就是我们系统中的根证书。所以说,给系统安装根证书需谨慎,安装即代表信任该Root CA,由它所签发的所有证书也都会被信任。
证书在https协议扮演重要角色,客户端与服务器建立TCP连接后,服务器首先下发自己的证书,客户端验证通过后随机生成一个密钥(用于后续对称加密的通信),然后用证书中的公钥加密它,再发送给服务器,所以中间人是无法得知这个密钥的,只能傻傻的看着双方说暗语。
比如在Chrome浏览器中,点击URL旁边的小锁,就可以查看网站证书信息:
-
证书的使用者、颁发者还有签名算法等信息
-
证书信任链
总结
内容还是太浅显了,一点实现细节都没有,简直就像科普。