1.简洁的解释:

1.服务器 用RSA生成公钥和私钥
2.把公钥放在证书里发送给客户端,私钥自己保存
3.客户端首先向一个权威的服务器检查证书的合法性,如果证书合法,客户端产生一段随机数,这个随机数就作为通信的密钥,我们称之为对称密钥,用公钥加密这段随机数,然后发送到服务器
4.服务器用密钥解密获取对称密钥,然后,双方就已对称密钥进行加密解密通信了
PS:非对称的RSA加密性能是非常低的,原因在于寻找大素数、大数计算、数据分割需要耗费很多的CPU周期,所以一般的HTTPS连接只在第一次握手时使用非对称加密,通过握手交换对称加密密钥,在之后的通信走对称加密。

2.详细的:

1.浏览器将自己支持的一套加密规则发送给网站。 
2.网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。 
3.浏览器获得网站证书之后浏览器要做以下工作: 
a) 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。 
b) 如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密。 
c) 使用约定好的HASH算法计算握手消息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站。 
4.网站接收浏览器发来的数据之后要做以下的操作: 
a) 使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证HASH是否与浏览器发来的一致。 
b) 使用密码加密一段握手消息,发送给浏览器。 
5.浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。

3.实现:

生成密钥、证书

第一步,为服务器端和客户端准备公钥、私钥

  1. # 生成服务器端私钥
  2. openssl genrsa -out server.key 1024
  3. # 生成服务器端公钥
  4. openssl rsa -in server.key -pubout -out server.pem
  5. # 生成客户端私钥
  6. openssl genrsa -out client.key 1024
  7. # 生成客户端公钥
  8. openssl rsa -in client.key -pubout -out client.pem

第二步,生成 CA 证书

  1. # 生成 CA 私钥
  2. openssl genrsa -out ca.key 1024
  3. # X.509 Certificate Signing Request (CSR) Management.
  4. openssl req -new -key ca.key -out ca.csr
  5. # X.509 Certificate Data Management.
  6. openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt

在执行第二步时会出现:

  1. ➜  keys  openssl req -new -key ca.key -out ca.csr
  2. You are about to be asked to enter information that will be incorporated
  3. into your certificate request.
  4. What you are about to enter is what is called a Distinguished Name or a DN.
  5. There are quite a few fields but you can leave some blank
  6. For some fields there will be a default value,
  7. If you enter '.', the field will be left blank.
  8. -----
  9. Country Name (2 letter code) [AU]:CN
  10. State or Province Name (full name) [Some-State]:Zhejiang
  11. Locality Name (eg, city) []:Hangzhou
  12. Organization Name (eg, company) [Internet Widgits Pty Ltd]:My CA
  13. Organizational Unit Name (eg, section) []:
  14. Common Name (e.g. server FQDN or YOUR name) []:localhost
  15. Email Address []:

注意,这里的 Organization Name (eg, company) [Internet Widgits Pty Ltd]: 后面生成客户端和服务器端证书的时候也需要填写,不要写成一样的!!!可以随意写如:My CA, My Server, My Client。

然后 Common Name (e.g. server FQDN or YOUR name) []: 这一项,是最后可以访问的域名,我这里为了方便测试,写成 localhost ,如果是为了给我的网站生成证书,需要写成 barretlee.com 。

第三步,生成服务器端证书和客户端证书

  1. # 服务器端需要向 CA 机构申请签名证书,在申请签名证书之前依然是创建自己的 CSR 文件
  2. openssl req -new -key server.key -out server.csr
  3. # 向自己的 CA 机构申请证书,签名过程需要 CA 的证书和私钥参与,最终颁发一个带有 CA 签名的证书
  4. openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
  5. # client 端
  6. openssl req -new -key client.key -out client.csr
  7. # client 端到 CA 签名
  8. openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt

此时,我们的 keys 文件夹下已经有如下内容了:

  1. .
  2. ├── https-client.js
  3. ├── https-server.js
  4. └── keys
  5. ├── ca.crt
  6. ├── ca.csr
  7. ├── ca.key
  8. ├── ca.pem
  9. ├── ca.srl
  10. ├── client.crt
  11. ├── client.csr
  12. ├── client.key
  13. ├── client.pem
  14. ├── server.crt
  15. ├── server.csr
  16. ├── server.key
  17. └── server.pem

看到上面两个 js 文件了么,我们来跑几个demo。

HTTPS本地测试

服务器代码:

  1. // file http-server.js
  2. var https = require('https');
  3. var fs = require('fs');
  4. var options = {
  5. key: fs.readFileSync('./keys/server.key'),
  6. cert: fs.readFileSync('./keys/server.crt')
  7. };
  8. https.createServer(options, function(req, res) {
  9. res.writeHead(200);
  10. res.end('hello world');
  11. }).listen(8000);

短短几行代码就构建了一个简单的 https 服务器,options 将私钥和证书带上。然后利用 curl 测试:

  1. ➜  https  curl https://localhost:8000
  2. curl: (60) SSL certificate problem: Invalid certificate chain
  3. More details here: http://curl.haxx.se/docs/sslcerts.html
  4. curl performs SSL certificate verification by default, using a "bundle"
  5. of Certificate Authority (CA) public keys (CA certs). If the default
  6. bundle file isn't adequate, you can specify an alternate file
  7. using the --cacert option.
  8. If this HTTPS server uses a certificate signed by a CA represented in
  9. the bundle, the certificate verification probably failed due to a
  10. problem with the certificate (it might be expired, or the name might
  11. not match the domain name in the URL).
  12. If you'd like to turn off curl's verification of the certificate, use
  13. the -k (or --insecure) option.

当我们直接访问时, curl https://localhost:8000

一堆提示,原因是没有经过 CA 认证,添加 -k 参数能够解决这个问题:

  1. ➜  https  curl -k https://localhost:8000
  2. hello world%

这样的方式是不安全的,存在我们上面提到的中间人攻击问题。可以搞一个客户端带上 CA 证书试试:

  1. // file http-client.js
  2. var https = require('https');
  3. var fs = require('fs');
  4. var options = {
  5. hostname: "localhost",
  6. port: 8000,
  7. path: '/',
  8. methed: 'GET',
  9. key: fs.readFileSync('./keys/client.key'),
  10. cert: fs.readFileSync('./keys/client.crt'),
  11. ca: [fs.readFileSync('./keys/ca.crt')]
  12. };
  13. options.agent = new https.Agent(options);
  14. var req = https.request(options, function(res) {
  15. res.setEncoding('utf-8');
  16. res.on('data', function(d) {
  17. console.log(d);
  18. });
  19. });
  20. req.end();
  21. req.on('error', function(e) {
  22. console.log(e);
  23. });

先打开服务器 node http-server.js ,然后执行

  1. ➜  https  node https-client.js
  2. hello world

如果你的代码没有输出

hello world ,说明证书生成的时候存在问题。也可以通过浏览器访问:

提示错误:

此服务器无法证明它是localhost;您计算机的操作系统不信任其安全证书。出现此问题的原因可能是配置有误或您的连接被拦截了。

原因是浏览器没有 CA 证书,只有 CA 证书,服务器才能够确定,这个用户就是真实的来自 localhost 的访问请求(比如不是代理过来的)。

你可以点击 继续前往localhost(不安全) 这个链接,相当于执行 curl -k https://localhost:8000 。如果我们的证书不是自己颁发,而是去靠谱的机构去申请的,那就不会出现这样的问题,因为靠谱机构的证书会放到浏览器中,浏览器会帮我们做很多事情。初次尝试的同学可以去 startssl.com 申请一个免费的证书。

参考链接:https://blog.csdn.net/abcd1101/article/details/71512809

https证书的验证过程与生成方法的更多相关文章

  1. APP中https证书有效性验证引发安全问题(例Fiddler可抓https包)

    原文: https://blog.csdn.net/woddle/article/details/71175140 在实际项目代码审计中发现,目前很多手机银行虽然使用了https通信方式,但是只是简单 ...

  2. 转载:HTTPS证书的产生过程详解

    1.RSA身份验证的隐患 身份验证和密钥协商是TLS的基础功能,要求的前提是合法的服务器掌握着对应的私钥.但RSA算法无法确保服务器身份的合法性,因为公钥并不包含服务器的信息,存在安全隐患:    客 ...

  3. 【腾讯Bugly干货分享】iOS 中 HTTPS 证书验证浅析

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/-fLLTtip509K6pNOTkflPQ 导语 本 ...

  4. linux自建https证书

    一.生成单向认证的https证书 建立服务器私钥,生成RSA秘钥. 会有两次要求输入密码, 然后获得了一个server.key文件. 以后使用此文件(通过openssl提供的命令或API)可能经常回要 ...

  5. TLS/HTTPS 证书生成与验证

    最近在研究基于ssl的传输加密,涉及到了key和证书相关的话题,走了不少弯路,现在总结一下做个备忘 科普:TLS.SSL.HTTPS以及证书 不少人可能听过其中的超过3个名词,但它们究竟有什么关联呢? ...

  6. [转]在 .NET 中远程请求 https 内容时,发生错误:根据验证过程,远程证书无效

    该文原网址:http://www.cnblogs.com/xwgli/p/5487930.html 在 .NET 中远程请求 https 内容时,发生错误:根据验证过程,远程证书无效.   当访问 h ...

  7. XmlDocument.Load(url) url是https远程时,报错" 基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。" "根据验证过程,远程证书无效。"

    XmlDocument.Load(url)  url是https远程时,报错" 基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系."   "根据验证过程, ...

  8. https 证书传递、验证和数据加密、解密过程解析

    我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取.所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议. HTTPS简介 HTTPS其实是有两部分组成:HTTP + SSL ...

  9. 免费生成https证书以及配置

    http升级到https需要在nginx的配置中加入证书信息,查询资料后确定生成证书两种方案   第一种:自签名证书,然后开启 CloudFlare 的 CDN 服务   //确定是否安装openss ...

随机推荐

  1. Java基础五(方法)

    今日内容介绍1.方法基础知识2.方法高级内容3.方法案例 ###01方法的概述 * A: 为什么要有方法 * 提高代码的复用性 * B: 什么是方法 * 完成特定功能的代码块. ###02方法的定义格 ...

  2. diskcache

    DiskCache: Disk Backed Cache DiskCache is an Apache2 licensed disk and file backed cache library, wr ...

  3. mysql深入

    使用存储过程 create procedure productpricing() begin select avg(prod_price) as priceaverage from products; ...

  4. windows知识

    文章目录 系统 修改远程桌面的端口号 IE选项中reset web setting不可用(灰色)的解决办法 重装系统后,修改默认程序安装目录.我的文档.桌面 路径 Keep network addre ...

  5. Architecture options to run a workflow engine

    This week a customer called and asked (translated into my own words and shortened): “We do composite ...

  6. 算法(第4版) (Robert Sedgewick / Kevin Wayne 著)

    第1章 基础 第2章 排序 第3章 查找 第4章 图 第5章 字符串 第1章 基础 public class Bag<T> : IEnumerable<T> { ]; ; pu ...

  7. PowerDesigner学习 ---- 系列文章

    一.PowerDesigner概述(系统分析与建模) 二.项目和框架矩阵 三.企业架构模型 四.业务处理模型 五.概念数据模型(CDM生成LDM,PDM和OOM) 六.物理数据模型(PDM逆向工程) ...

  8. Hi3516CV300 sample -> region

  9. python selenium-webdriver 生成测试报告 (十四)

    测试最后的一个重要的过程就是生成一份完整的测试报告,生成测试报告的主要是通过python的一个第三方模块HTMLTestRunner.py生成,但是生成的测试报告不是特别的美观,而且没有办法统计测试结 ...

  10. C语言 二维数组(指针)动态分配和释放(转)

    C 二维数组(指针)动态分配和释放 先明确下概念: 所谓32位处理器就是一次只能处理32位,也就是4个字节的数据,而64位处理器一次就能处理64位,即8个字节的数据.如果我们将总长128位的指令分别按 ...