https的公钥和私钥

原连接:
https://blog.csdn.net/afanti222/article/details/79631040

文中首先解释了加密解密的一些基础知识和概念,而后经过一个加密通讯过程的例子说明了加密算法的做用,以及数字证书的出现所起的做用。接着对数字证书作一个详细的解释,并讨论一下windows中数字证书的管理,最后演示使用makecert生成数字证书。若是发现文中有错误的地方,或者有什么地方说得不够清楚,欢迎指出!
1、基础知识 这部份内容主要解释一些概念和术语,最好是先理解这部份内容。 1.1、公钥密码体制(public-key cryptography) 公钥密码体制分为三个部分,公钥、私钥、加密解密算法,它的加密解密过程以下: 加密:经过加密算法和公钥对内容(或者说明文)进行加密,获得密文。加密过程须要用到公钥。 解密:经过解密算法和私钥对密文进行解密,获得明文。解密过程须要用到解密算法和私钥。注意,由公钥加密的内容,只能由私钥进行解密,也就是说,由公钥加密的内容,若是不知道私钥,是没法解密的。 公钥密码体制的公钥和算法都是公开的(这是为何叫公钥密码体制的缘由),私钥是保密的。你们都以使用公钥进行加密,可是只有私钥的持有者才能解密。在实际的使用中,有须要的人会生成一对公钥和私钥,把公钥发布出去给别人使用,本身保留私钥。 1.2、对称加密算法(symmetric key algorithms) 在对称加密算法中,加密使用的密钥和解密使用的密钥是相同的。也就是说,加密和解密都是使用的同一个密钥。所以对称加密算法要保证安全性的话,密钥要作好保密,只能让使用的人知道,不能对外公开。这个和上面的公钥密码体制有所不一样,公钥密码体制中加密是用公钥,解密使用私钥,而对称加密算法中,加密和解密都是使用同一个密钥,不区分公钥和私钥。 // 密钥,通常就是一个字符串或数字,在加密或者解密时传递给加密/解密算法。前面在公钥密码体制中说到的公钥、私钥就是密钥,公钥是加密使用的密钥,私钥是解密使用的密钥。 1.3、非对称加密算法(asymmetric key algorithms) 在非对称加密算法中,加密使用的密钥和解密使用的密钥是不相同的。前面所说的公钥密码体制就是一种非对称加密算法,他的公钥和是私钥是不能相同的,也就是说加密使用的密钥和解密使用的密钥不一样,所以它是一个非对称加密算法。 1.4、RSA简介 RSA是一种公钥密码体制,如今使用得很普遍。若是对RSA自己有兴趣的,后面看我有没有时间写个RSA的具体介绍。 RSA密码体制是一种公钥密码体制,公钥公开,私钥保密,它的加密解密算法是公开的。 由公钥加密的内容能够而且只能由私钥进行解密,而且由私钥加密的内容能够而且只能由公钥进行解密。也就是说,RSA的这一对公钥、私钥均可以用来加密和解密,而且一方加密的内容能够由而且只能由对方进行解密。 1.5、签名和加密 咱们说加密,是指对某个内容加密,加密后的内容还能够经过解密进行还原。 好比咱们把一封邮件进行加密,加密后的内容在网络上进行传输,接收者在收到后,经过解密能够还原邮件的真实内容。 这里主要解释一下签名,签名就是在信息的后面再加上一段内容,能够证实信息没有被修改过,怎么样能够达到这个效果呢?通常是对信息作一个hash计算获得一个hash值,注意,这个过程是不可逆的,也就是说没法经过hash值得出原来的信息内容。在把信息发送出去时,把这个hash值加密后作为一个签名和信息一块儿发出去。 接收方在收到信息后,会从新计算信息的hash值,并和信息所附带的hash值(解密后)进行对比,若是一致,就说明信息的内容没有被修改过,由于这里hash计算能够保证不一样的内容必定会获得不一样的hash值,因此只要内容一被修改,根据信息内容计算的hash值就会变化。固然,不怀好意的人也能够修改信息内容的同时也修改hash值,从而让它们能够相匹配,为了防止这种状况,hash值通常都会加密后(也就是签名)再和信息一块儿发送,以保证这个hash值不被修改。至于如何让别人能够解密这个签名,这个过程涉及到数字证书等概念,咱们后面在说到数字证书时再详细说明,这里您先只需先理解签名的这个概念。 2、一个加密通讯过程的演化 咱们来看一个例子,如今假设“服务器”和“客户”要在网络上通讯,而且他们打算使用RSA(参看前面的RSA简介)来对通讯进行加密以保证谈话内容的安全。因为是使用RSA这种公钥密码体制,“服务器”须要对外发布公钥(算法不须要公布,RSA的算法你们都知道),本身留着私钥。“客户”经过某些途径拿到了“服务器”发布的公钥,客户并不知道私钥。“客户”具体是经过什么途径获取公钥的,咱们后面再来讲明,下面看一下双方如何进行保密的通讯: 2.1 第一回合: “客户”->“服务器”:你好 “服务器”->“客户”:你好,我是服务器 “客户”->“服务器”:???? 由于消息是在网络上传输的,有人能够冒充本身是“服务器”来向客户发送信息。例如上面的消息能够被黑客截获以下: “客户”->“服务器”:你好 “服务器”->“客户”:你好,我是服务器 “客户”->“黑客”:你好 // 黑客在“客户”和“服务器”之间的某个路由器上截获“客户”发给服务器的信息,而后本身冒充“服务器” “黑客”->“客户”:你好,我是服务器 所以“客户”在接到消息后,并不能确定这个消息就是由“服务器”发出的,某些“黑客”也能够冒充“服务器”发出这个消息。如何肯定信息是由“服务器”发过来的呢?有一个解决方法,由于只有服务器有私钥,因此若是只要可以确认对方有私钥,那么对方就是“服务器”。所以通讯过程能够改进为以下: 2.2 第二回合: “客户”->“服务器”:你好 “服务器”->“客户”:你好,我是服务器 “客户”->“服务器”:向我证实你就是服务器 “服务器”->“客户”:你好,我是服务器 {你好,我是服务器}[私钥|RSA] // 注意这里约定一下,{} 表示RSA加密后的内容,[ | ]表示用什么密钥和算法进行加密,后面的示例中都用这种表示方式,例如上面的 {你好,我是服务器}[私钥|RSA] 就表示用私钥对“你好,我是服务器”进行加密后的结果。 为了向“客户”证实本身是“服务器”, “服务器”把一个字符串用本身的私钥加密,把明文和加密后的密文一块儿发给“客户”。对于这里的例子来讲,就是把字符串 “你好,我是服务器”和这个字符串用私钥加密后的内容 {你好,我是服务器}[私钥|RSA] 发给客户。 “客户”收到信息后,她用本身持有的公钥解密密文,和明文进行对比,若是一致,说明信息的确是由服务器发过来的。也就是说“客户”把 {你好,我是服务器}[私钥|RSA] 这个内容用公钥进行解密,而后和“你好,我是服务器”对比。由于由“服务器”用私钥加密后的内容,由而且只能由公钥进行解密,私钥只有“服务器”持有,因此若是解密出来的内容是可以对得上的,那说明信息必定是从“服务器”发过来的。 假设“黑客”想冒充“服务器”: “黑客”->“客户”:你好,我是服务器 “客户”->“黑客”:向我证实你就是服务器 “黑客”->“客户”:你好,我是服务器 {你好,我是服务器}[???|RSA] //这里黑客没法冒充,由于他不知道私钥,没法用私钥加密某个字符串后发送给客户去验证。 “客户”->“黑客”:???? 因为“黑客”没有“服务器”的私钥,所以它发送过去的内容,“客户”是没法经过服务器的公钥解密的,所以能够认定对方是个冒牌货! 到这里为止,“客户”就能够确认“服务器”的身份了,能够放心和“服务器”进行通讯,可是这里有一个问题,通讯的内容在网络上仍是没法保密。为何没法保密呢?通讯过程不是能够用公钥、私钥加密吗?其实用RSA的私钥和公钥是不行的,咱们来具体分析下过程,看下面的演示: 2.3 第三回合: “客户”->“服务器”:你好 “服务器”->“客户”:你好,我是服务器 “客户”->“服务器”:向我证实你就是服务器 “服务器”->“客户”:你好,我是服务器 {你好,我是服务器}[私钥|RSA] “客户”->“服务器”:{个人账号是aaa,密码是123,把个人余额的信息发给我看看}[公钥|RSA] “服务器”->“客户”:{你的余额是100元}[私钥|RSA] 注意上面的的信息 {你的余额是100元}[私钥],这个是“服务器”用私钥加密后的内容,可是咱们以前说了,公钥是发布出去的,所以全部的人都知道公钥,因此除了“客户”,其它的人也能够用公钥对{你的余额是100元}[私钥]进行解密。因此若是“服务器”用私钥加密发给“客户”,这个信息是没法保密的,由于只要有公钥就能够解密这内容。然而“服务器”也不能用公钥对发送的内容进行加密,由于“客户”没有私钥,发送个“客户”也解密不了。 这样问题就又来了,那又如何解决呢?在实际的应用过程,通常是经过引入对称加密来解决这个问题,看下面的演示: 2.4 第四回合: “客户”->“服务器”:你好 “服务器”->“客户”:你好,我是服务器 “客户”->“服务器”:向我证实你就是服务器 “服务器”->“客户”:你好,我是服务器 {你好,我是服务器}[私钥|RSA] “客户”->“服务器”:{咱们后面的通讯过程,用对称加密来进行,这里是对称加密算法和密钥}[公钥|RSA] //蓝色字体的部分是对称加密的算法和密钥的具体内容,客户把它们发送给服务器。 “服务器”->“客户”:{OK,收到!}[密钥|对称加密算法] “客户”->“服务器”:{个人账号是aaa,密码是123,把个人余额的信息发给我看看}[密钥|对称加密算法] “服务器”->“客户”:{你的余额是100元}[密钥|对称加密算法] 在上面的通讯过程当中,“客户”在确认了“服务器”的身份后,“客户”本身选择一个对称加密算法和一个密钥,把这个对称加密算法和密钥一块儿用公钥加密后发送给“服务器”。注意,因为对称加密算法和密钥是用公钥加密的,就算这个加密后的内容被“黑客”截获了,因为没有私钥,“黑客”也无从知道对称加密算法和密钥的内容。 因为是用公钥加密的,只有私钥可以解密,这样就能够保证只有服务器能够知道对称加密算法和密钥,而其它人不可能知道(这个对称加密算法和密钥是“客户”本身选择的,因此“客户”本身固然知道如何解密加密)。这样“服务器”和“客户”就能够用对称加密算法和密钥来加密通讯的内容了。 总结一下,RSA加密算法在这个通讯过程当中所起到的做用主要有两个: 由于私钥只有“服务器”拥有,所以“客户”能够经过判断对方是否有私钥来判断对方是不是“服务器”。 客户端经过RSA的掩护,安全的和服务器商量好一个对称加密算法和密钥来保证后面通讯过程内容的安全。 若是这里您理解了为何不用RSA去加密通讯过程,而是要再肯定一个对称加密算法来保证通讯过程的安全,那么就说明前面的内容您已经理解了。(若是不清楚,再看下2.3和2.4,若是仍是不清楚,那应该是咱们说清楚,您能够留言提问。) 到这里,“客户”就能够确认“服务器”的身份,而且双方的通讯内容能够进行加密,其余人就算截获了通讯内容,也没法解密。的确,好像通讯的过程是比较安全了。 可是这里还留有一个问题,在最开始咱们就说过,“服务器”要对外发布公钥,那“服务器”如何把公钥发送给“客户”呢?咱们第一反应可能会想到如下的两个方法: a)把公钥放到互联网的某个地方的一个下载地址,事先给“客户”去下载。 b)每次和“客户”开始通讯时,“服务器”把公钥发给“客户”。 可是这个两个方法都有必定的问题, 对于a)方法,“客户”没法肯定这个下载地址是否是“服务器”发布的,你凭什么就相信这个地址下载的东西就是“服务器”发布的而不是别人伪造的呢,万一下载到一个假的怎么办?另外要全部的“客户”都在通讯前事先去下载公钥也很不现实。 对于b)方法,也有问题,由于任何人均可以本身生成一对公钥和私钥,他只要向“客户”发送他本身的私钥就能够冒充“服务器”了。示意以下: “客户”->“黑客”:你好 //黑客截获“客户”发给“服务器”的消息 “黑客”->“客户”:你好,我是服务器,这个是个人公钥 //黑客本身生成一对公钥和私钥,把公钥发给“客户”,本身保留私钥 “客户”->“黑客”:向我证实你就是服务器 “黑客”->“客户”:你好,我是服务器 {你好,我是服务器}[黑客本身的私钥|RSA] //客户收到“黑客”用私钥加密的信息后,是能够用“黑客”发给本身的公钥解密的,从而会误认为“黑客”是“服务器” 所以“黑客”只须要本身生成一对公钥和私钥,而后把公钥发送给“客户”,本身保留私钥,这样因为“客户”能够用黑客的公钥解密黑客的私钥加密的内容,“客户”就会相信“黑客”是“服务器”,从而致使了安全问题。这里问题的根源就在于,你们均可以生成公钥、私钥对,没法确认公钥对究竟是谁的。 若是可以肯定公钥究竟是谁的,就不会有这个问题了。例如,若是收到“黑客”冒充“服务器”发过来的公钥,通过某种检查,若是可以发现这个公钥不是“服务器”的就行了。 为了解决这个问题,数字证书出现了,它能够解决咱们上面的问题。先大概看下什么是数字证书,一个证书包含下面的具体内容: 证书的发布机构 证书的有效期 公钥 证书全部者(Subject) 签名所使用的算法 指纹以及指纹算法 证书的内容的详细解释会在后面详细解释,这里先只须要搞清楚一点,数字证书能够保证数字证书里的公钥确实是这个证书的全部者(Subject)的,或者证书能够用来确认对方的身份。也就是说,咱们拿到一个数字证书,咱们能够判断出这个数字证书究竟是谁的。至因而如何判断的,后面会在详细讨论数字证书时详细解释。如今把前面的通讯过程使用数字证书修改成以下: 2.5 第五回合: “客户”->“服务器”:你好 “服务器”->“客户”:你好,我是服务器,这里是个人数字证书 //这里用证书代替了公钥 “客户”->“服务器”:向我证实你就是服务器 “服务器”->“客户”:你好,我是服务器 {你好,我是服务器}[私钥|RSA] 注意,上面第二次通讯,“服务器”把本身的证书发给了“客户”,而不是发送公钥。“客户”能够根据证书校验这个证书究竟是不是“服务器”的,也就是能校验这个证书的全部者是否是“服务器”,从而确认这个证书中的公钥的确是“服务器”的。后面的过程和之前是同样,“客户”让“服务器”证实本身的身份,“服务器”用私钥加密一段内容连同明文一块儿发给“客户”,“客户”把加密内容用数字证书中的公钥解密后和明文对比,若是一致,那么对方就确实是“服务器”,而后双方协商一个对称加密来保证通讯过程的安全。到这里,整个过程就完整了,咱们回顾一下: 2.6 完整过程: step1: “客户”向服务端发送一个通讯请求 “客户”->“服务器”:你好 step2: “服务器”向客户发送本身的数字证书。证书中有一个公钥用来加密信息,私钥由“服务器”持有 “服务器”->“客户”:你好,我是服务器,这里是个人数字证书 step3: “客户”收到“服务器”的证书后,它会去验证这个数字证书究竟是不是“服务器”的,数字证书有没有什么问题,数字证书若是检查没有问题,就说明数字证书中的公钥确实是“服务器”的。检查数字证书后,“客户”会发送一个随机的字符串给“服务器”用私钥去加密,服务器把加密的结果返回给“客户”,“客户”用公钥解密这个返回结果,若是解密结果与以前生成的随机字符串一致,那说明对方确实是私钥的持有者,或者说对方确实是“服务器”。 “客户”->“服务器”:向我证实你就是服务器,这是一个随机字符串 //前面的例子中为了方便解释,用的是“你好”等内容,实际状况下通常是随机生成的一个字符串。 “服务器”->“客户”:{一个随机字符串}[私钥|RSA] step4: 验证“服务器”的身份后,“客户”生成一个对称加密算法和密钥,用于后面的通讯的加密和解密。这个对称加密算法和密钥,“客户”会用公钥加密后发送给“服务器”,别人截获了也没用,由于只有“服务器”手中有能够解密的私钥。这样,后面“服务器”和“客户”就均可以用对称加密算法来加密和解密通讯内容了。 “服务器”->“客户”:{OK,已经收到你发来的对称加密算法和密钥!有什么能够帮到你的?}[密钥|对称加密算法] “客户”->“服务器”:{个人账号是aaa,密码是123,把个人余额的信息发给我看看}[密钥|对称加密算法] “服务器”->“客户”:{你好,你的余额是100元}[密钥|对称加密算法] …… //继续其它的通讯