故事的起源
私密性
之前,用户a想给用户b发消息,a希望他自己发出现的消息,只能被b读懂。也就是说a希望发出去的数据是被加密过的,收到消息的人可以是b,c,d,e等等。但是只有b能读懂。
这个需求很简单,加密即可。啥意思,如果a这个用户想发送的原始数据是485,然后a给这个458进行加密,怎么加密呢?给每一个数字都加一个"2"。这样一来,发出去的消息就变成了670。然后a再把加密方法(给每一个数字都加一个"2")只告诉b。那之后当b收到670,再逆着进行运算,就能从670得到458。此之谓加密。
完整性
什么意思,a给b发送了一个670(加密后的消息)。但是消息在发送过程中篡改了(有可能是某些人故意的,也有可能是网络各种异常),b收到的消息变成了67或者变成了671。那此时无论b怎么进行逆向解密都不能得到a最初想发送的485这个数据。(这里的关键问题不是b如何修复67变成670,而是b怎么才能知道此刻他收到的67是一份并不准确的残缺信息!)
唯一性
唯一性这个名称不准确。准确的需求就是,b收到了一组消息,但是谁能保证这个消息就真的是a发出的呢?a后面有没有可能说我从来就没有发过消息!!
秘钥的实现思路
通过某个工具生产一组字符串,一个叫私钥,一个叫公钥。
一组公钥私钥的功能就是
公钥和私钥成对出现
公开的密钥叫公钥,只有自己知道的叫私钥
用公钥加密的数据只有对应的私钥可以解密
用私钥加密的数据只有对应的公钥可以解密
如果可以用公钥解密,则必然是对应的私钥加的密
如果可以用私钥解密,则必然是对应的公钥加的密
还是在a给b发消息的例子里。每个用户都有一组自己的秘钥,一个公钥一个私钥。
首先,a把自己的公钥给b,私钥自己保存;b也把自己的公钥给a,然后私钥自己保存。
- case1 私密性
当a给b发消息的时候,a用b给的公钥进行加密。这样等b收到消息后,b再用b自己的私钥进行解密。
这样一来,a发出去的消息,即使被c收到了,但是由于c没有b的私钥,也就没法解密(c也就看不懂自己收到的消息了)。这就满足了上面说的私密性。 - case2 完整性
当a给b发消息的时候,用a自己的私钥对自己要发的信息进行一下完整性校验。等到b收到消息之后,就先用a的公钥进行数据验证,看看数据是不是完整的。这就满足了上面说的完整性。 - case3 唯一性
当a给b发消息的时候,就直接把a的私钥当做一个印章,盖在信息上(然后用b的公钥进行加密)。等到b收到消息后,用b自己的私钥进行解密,之后发现了a的私钥。那就证明了这个消息真的是a发送的。a就不能赖账了。这就满足了上面说的唯一性。
另外你说假如a的私钥被c偷走了,那这怎么办?
那没办法,公钥私钥机制只是从技术层面解决问题,c偷了a的秘钥,这显然已经超脱技术层面了。
应用
- linux服务器的登录
当用户想从服务器a登录服务器b的时候。
先使用工具(例如ssh-keygen)生成一组秘钥对,然后把公钥放到b上,从a上用私钥进行登录。之后如果想从c上登录b,那只用把之前的私钥也给c发一份即可。 - git上上传下载代码
与登录linux服务器一样,把私钥放在允许登录某个账号的机器上,然后把公钥上传到git的账户管理里。
一点问题
- case1
有个问题,直接用用户名密码的方式登录服务器不行么?为什么非得用秘钥机制?
因为大家用的密码大多数情况下都很简单,例如admin,123456等等,很容易被破解。当然如果你说自己使用的密码是三十几位,包括大小写字母,数字,特殊字符那当我没说。 - case2
某些用户说,公钥私钥可以替换使用。
我自己也不能确定上面说法是不是对的。但是建议大家还是按照标准用法:
公钥就是公钥,散播出去;
私钥就是私钥,自己保存好,不要给别人。
参考文档
https://zhuanlan.zhihu.com/p/113522792