之前走路上想起一个关于CA的问题:
为什么CA证书信息需要使用【摘要算法】生成指纹,然后再“一起”使用加密算法加密,我认为只要客户端能够解密,不就代表里面的信息没有被篡改嘛,为什么还需要包含指纹信息。问了下学习群里面的同学,说是为了“双重确认”信息没有被篡改。后来查资料才知道:CA信息是明文的,只有签名才是被加密的,这样能同时保证签名和CA信息都没有被篡改。
感觉自己对流程还是不够清晰。所以重新精简整理了下整个流程以及具体的实现,完全基于个人理解简化为关键点来说明。详细内容可参考:https://blog.csdn.net/u011877584/article/details/81119441
本篇文章主要包含:
- 相关算法
- CA机构,CA证书
- Https下client和server的交互过程
- 具体实现
相关算法
-
信息摘要算法(常见MD5)
MD5能够将原文算法生成16位或者32位固定长度字符,原文改变会导致生成结果改变。应用场景大部分为签名,确保原文信息没有被篡改。具有不可逆性,即理论上不能解密出原文。
-
非对称加密算法(常见RSA)
公私钥成对出现。常用技巧是:私钥加密公钥解密=>确保信息来源正确,公钥加密私钥解密=>确保只有固定人能收到信息,这两点理解很关键。具有可逆性,即可以解密出原文。
-
对称加密算法(常用DES)
相对非对称加密来说只有一个密钥产生,可用于加密解密。具有可逆性,即可以解密出原文。加密解密效率较非对称加密高。
CA机构,CA证书
CA全称Certificate Authorities,CA机构即是证书认证机构,CA证书即使认证机构证书。CA机构是全球性质的大型机构(能够为自己颁发的证书负责),颁发的证书也是实现https安全通信的关键。
为什么需要https,为什么需要CA?
因为http不安全,因为http协议本身就是明文去传输数据,很容易被类似于Charles或者Wireshark这类的工具截获信息。这样会造成:
客户端不知道访问的服务器是否为真的服务端(钓鱼网站)
-
服务端不知道访问者是不是真的客户端(冒名顶替)
简单来讲客户端和服务端双方不信任。所以我们需要加密算法来加密传递的信息。
我们可以直接利用类似DES的对称加密算法加密通信信息。有两个问题:
-
为什么是【对称加密算法】而不是【非对称加密算法】?
因为非对称加密算法中公钥是曝光在公众视野的,使用公私钥传递信息没办法确保通信双方信息都不会被截获。并且非对称加密效率不如对称加密效率高。
-
如果使用对称加密算法的话如何将密钥传递给对方?
可以使用非对称加密算法包裹这个密钥传递给对方。(注意这里是第一对公私钥,用于包裹对称加密密钥)
那么问题就变成了:如何将非对称加密算法中的公钥给对方?
CA机构和CA证书登场了!当客户端访问服务端时,服务端因为使用CA服务的原因会向客户端发送安全证书来证明自己是真的认证过的服务器,证书中包含信息:
- Issuer (证书的发布机构)
- Valid from , Valid to (证书的有效期)
- Public key (公钥)
- Subject (主题)
- Signature algorithm (签名所使用的算法)
- Thumbprint, Thumbprint algorithm (指纹以及指纹算法)
这里的指纹是对前面信息进行摘要算法,来确保证书信息没有被篡改。同时为了确保指纹本身是没有被篡改的,于是使用证书机构的私钥(注意这里是第二对公私钥(证书),也就是说CA机构为自己也生成了一个证书)用签名算法进行加密(私钥加密确保信息来源无误)。想要获取加密前的指纹信息来确保证书信息没有被篡改就必须获取该证书机构的公钥,那么从哪里获取CA机构证书的公钥呢?答案是从自己的电脑上。
这个证书发布机构的数字证书(一般由他自己生成)在我们的操作系统刚安装好时(例如windows等操作系统),这些证书发布机构的数字证书就已经被微软(或者其它操作系统的开发机构)安装在操作系统中了,微软等公司会根据一些权威安全机构的评估选取一些信誉很好并且通过一定的安全认证的证书发布机构,把这些证书发布机构的证书默认就安装在操作系统里面了,并且设置为操作系统信任的数字证书。
可以运行certmgr.msc 查看电脑上安装的证书,下图是SecureTrust CA这个机构的CA证书。
浏览器会自动根据名称去系统找到对应CA机构的证书(第二对公私钥),然后取出公钥对证书中的签名进行解密获得加密前的指纹信息,然后对证书信息用对应的算法进行hash,将结果和指纹进行对比,相同则表示证书没有被篡改。
Https下client和server的交互过程
完整过程如下:
- client访问server,server返回证书,证书信息中包含有证书基本信息,公钥(第一对公私钥),指纹信息,还有跟随证书的被CA机构私钥(第二对公私钥)加密后的签名,客户端根据CA名称从操作系统取出对应的公钥对其进行解密,解密成功表示签名正确并且得到指纹,再去对证书信息用指纹算法进行hash对比指纹,相同表示证书信息未被篡改。
- client获取到一个公钥(第一对公私钥),client生成一个对称加密算法和密钥用于后面通信的加密和解密,这个数据被截取了也没关系,因为只有server能用私钥(第一对公私钥)解密,server告知client已收到了对称加密算法和密钥,client接下来就可以使用这个对称解密算法和密钥和server进行安全通信。(这里省略了client和server交流支持哪一种加密算法的过程)
具体实现
当公司使用CA服务的时候,CA公司就会提该公司生成一个CA证书(前文中提到的第一对公私钥),同时还会将私钥给到公司。这个私钥不能泄露,在公司服务器部署完成证书和私钥之后,就会按照上述流程进行安全通信。
可以去像CA公司申请证书,如果是个人网站也可以考虑使用免费的SSL证书。可以使用Certbot申请免费证书。
官网有很详细的步骤。Certbot能自动从nginx.conf中加载出可能需要被SSL加密的域名,并且可以选择是全自动生成并且配置还是只是生成证书和密钥手动进行配置,很方便。
这里使用的是Certbot自动配置,图片中的fullchain.pem和privkey.pem分别为生成的证书和私钥。也可以手动配置证书私钥。