HTTPS的基本工作原理想必对于许多开发者来说是非常熟悉的了,我们一起先回忆一下HTTP常见的八股文中的描述:

  1. 客户端(浏览器)访问 HTTPS 的URL;
  2. 服务器返回 HTTPS 使用的 CA 证书;
  3. 客户端(浏览器)验证 CA 证书是否为合法证书;
  4. 验证通过,证书合法,生成一串随机数并使用公钥(证书中提供的)进行加密;
  5. 发送公钥加密后的随机数给服务器;
  6. 服务器拿到密文,通过私钥进行解密,获取到随机数(公钥加密,私钥解密,反之也可以);
  7. 服务器把要发送给浏览器的内容,使用随机数进行加密后传输给客户端(浏览器);
  8. 此时客户端(浏览器)可以使用随机数进行解密,获取到服务器的真实传输内容。

大体的过程是这样的,从整个过程中可以看出来,整个流程中涉及到了多个交互过程,主要分为了客户端、浏览器、以及CA之间的交互,还是比较复杂的,尤其是要具体知道每一步骤的其中细节,也是非常多的内容,所以这篇文章不是要去分析每一步的工作机制和原理,这篇文章主要内容是如何使用自签证书完成这一个过程,从而使我们能够进一步的对其有个初步的认识,如果对这其中细节感兴趣的,可以自行学习下,或者可能之后我也会对其进行深入的研究再和大家分享学习。

那么我们回到我们的主题里,首先需要知道CA证书是什么,CA是证书颁发机构(Certificate Authority)的缩写,那么CA证书就是证书机构颁发的一种数字证书,为什么需要这个机构来颁发证书呢?可以理解为就是一个第三方担保机构,这个担保机构保证了在客户端和服务器的通讯阶段的安全,这样客户端只要是看到证书是这个担保机构担保过的,那就会认可这个服务器并和它进行后续交互,反之其他证书都是不合法的,不会进行更进一步的交互了。

其次,这个证书不光是用来证明其合法性,其中还包含了一个公钥,公钥是什么呢?这边就涉及到一些密码学相关知识点了,我们需要先知道非对称加密的一点概念,可以猜出来,有非对称加密那肯定有对称加密,对称加密就是使用同一把密钥进行加密和解密,而非对称加密会用到2个密钥,一把公钥和一把私钥进行加密和解密,公钥会公开出去给客户端,而私钥会保存在本地防止泄漏,所以会更安全,使用这个公钥加密后的数据可以被私钥解开,反过来也是一样的,在上面的HTTPS的连接过程中,1-6步骤所涉及到的就是非对称加解密过程,而后续则会采用对称加密的方式,即使用一个随机数充当了对称加密的密钥进行了通讯,这样一方面是为了提高通讯的效率更重要的是为了保证安全,因为如果还使用原有的公钥和私钥的方式在服务端使用私钥加密,那么只要有公钥的客户端都可以截获服务端发来的信息进行解密,显然这样是不行的。对加密感兴趣的小伙伴可以自行百度看看,这边先不展开了。

知道了概念后,那自签证书的概念就是我们自己充当这个CA机构给自己颁发一个证书,然后想办法让客户端信任这个证书(一般的默认做法是系统会有一个受信任的证书列表,其中就会有存放一些CA机构的根证书),并且证书里面包含了我们的公钥,客户端使用这个公钥进行数据加密,再传输数据,服务端接收并用私钥解开,从而完成整个加解密的通讯过程。那接下来我们就来模拟这样一个通讯过程

首先,我们需要把自己先扮演成CA机构,根据非对称加密的概念,我们需要有一对密钥,对应一把公钥和一把私钥,私钥放在自己身边,公钥提供出去,这边需要注意的是不能把他看成是服务端,CA机构是在客户端和服务端两者之间的一个存在,这边理解了后,我们先来创建一把私钥,可以使用openssl来生成

Administrator@PC-20210427XPHC MINGW64 ~/Desktop/crt/crtDemo
$ openssl genrsa -out rootca.key 4096
Generating RSA private key, 4096 bit long modulus
................................................................++
...........++
e is 65537 (0x10001)

这样我们就生成了rootca.key的私钥文件,这个私钥是必须要保护好的,不能泄漏,然后我们来生成公钥,这边我们不会直接生成一把公钥对外开放,而是用上面提到的证书,为什么不直接用公钥呢?其实上面已经提到了,因为公钥私钥随便谁都可以生成出来,所以更重要的是要让客户端可以确认到这把公钥是否是受信任的,如果是受信任的才会使用这把公钥去和服务端交互,所以现在来生成一个带公钥的证书,我们可以叫他根证书

生成req请求文件,req请求文件用来生成证书的时候使用,其中包含了一些重要的信息,如证书所有者的一些信息等

Administrator@PC-20210427XPHC MINGW64 ~/Desktop/crt/rootCrt
$ openssl req -new -out rootca.csr -key rootca.key
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:cn
State or Province Name (full name) [Some-State]:sz
Locality Name (eg, city) []:sz
Organization Name (eg, company) [Internet Widgits Pty Ltd]:dobefa
Organizational Unit Name (eg, section) []:it
Common Name (e.g. server FQDN or YOUR name) []:karl
Email Address []:a.karl.com
string is too long, it needs to be less than  64 bytes long
Email Address []:a.karl.comPlease enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:82468246
An optional company name []:dd

接着我们通过csr和key来生成根证书,会使用到x509工具,这样生成会比较便捷,不会依赖太多的openssl的知识

Administrator@PC-20210427XPHC MINGW64 ~/Desktop/crt/crtDemo
$ openssl x509 -req -in rootca.csr -out rootca.crt -signkey rootca.key -days 36500
Signature ok
subject=/C=cn/ST=sz/L=sz/O=dobefa/OU=it/CN=karl/emailAddress=a.karl.com
Getting Private key

生成出rootca.crt,这个证书就是CA机构会预先在客户端中的受信任列表中埋下的根证书,其中包括了证书的所有者信息和公钥信息,有了这些信息,客户端就能通过这些信息来验证服务端返回的CA证书的合法性了

然后我们CA机构就可以开张营业了,CA机构会先把自己的证书让客户端放到其受信任的证书列表里,这边的客户端可以是Android系统,可以是Android的APP,也可以是Windows系统,也或者是Windows上的一个浏览器。我们这边先以Windows为例,把我们的CA证书植入进Windows的受信任列表中去,首先打开mmc

添加删除管理单元

选证书,添加

选计算机账户

本地计算机

完成后,就可以在列表中看到受信任的证书列表了

找到刚刚生成的ca根证书

安装证书,加入受信任列表

刷新刚刚的证书列表,就可以看到我们刚刚的证书

完成后,我们的CA机构就可以给别人颁发证书了,当然这边也是给我们自己颁发咯

我们来创建server密钥

Administrator@PC-20210427XPHC MINGW64 ~/Desktop/crt/crtDemo
$ openssl genrsa -out server.key 4096
Generating RSA private key, 4096 bit long modulus
.........................................................................................................................++
.................................................................................................................................................................................++
e is 65537 (0x10001)

创建请求文件

Administrator@PC-20210427XPHC MINGW64 ~/Desktop/crt/crtDemo
$ openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:cn
State or Province Name (full name) [Some-State]:js
Locality Name (eg, city) []:sz
Organization Name (eg, company) [Internet Widgits Pty Ltd]:dobefa
Organizational Unit Name (eg, section) []:it
Common Name (e.g. server FQDN or YOUR name) []:karl server
Email Address []:test.server.comPlease enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:82468246
An optional company name []:server

使用根证书签发证书

Administrator@PC-20210427XPHC MINGW64 ~/Desktop/crt/crtDemo
$ openssl x509 -req -in server.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -out server.crt -days 36500
Signature ok
subject=/C=cn/ST=js/L=sz/O=dobefa/OU=it/CN=karl server/emailAddress=test.server.com
Getting CA Private Key

做完这些步骤我们得到了一个server.crt,这个就是我们服务器的CA证书啦,这个服务端的CA证书是通过CA机构的私钥和CA根证书进行签名得到的,这样做会形成一个证书关联,这样我们就知道了这个服务器证书是出自哪个CA机构的哪张证书的了,我们可以查看下百度的证书会比较清楚,google浏览器为例

这个证书有三层的结构,根证书是GlobalSign的根证书,这是一个知名的CA机构,中间证书是GlobalSign使用根证书所生成出来的二级证书,而子证书就是GlobalSign颁发给baidu的CA证书了,大多数的CA证书都是通过二级CA来签发的,如果要实现这种结构的证书签署,会需要额外的一些配置来实现,所以我们这边暂不考虑这种做法,我们这边直接使用根CA进行签发,效果是一样的,这篇文章主要为了学习如何自签一个证书并完成https的交互过程,所以对证书签发感兴趣的同学可以学习更多关于openssl的知识。

接着,我们现在可以来试一下这个证书了,我们用go写一个非常简单的https服务器

package mainimport (_ "github.com/icattlecoder/godaemon""net/http""github.com/gin-gonic/gin"
)func setupRouter() *gin.Engine {// Disable Console Color// gin.DisableConsoleColor()r := gin.Default()// Ping testr.GET("/ping", func(c *gin.Context) {c.String(http.StatusOK, "pong")})return r
}func main() {r := setupRouter()// Listen and Server in 0.0.0.0:8080r.RunTLS(":8081", "C:\\Users\\Administrator\\Desktop\\crt\\crtDemo\\server.crt", "C:\\Users\\Administrator\\Desktop\\crt\\crtDemo\\server.key")
}

上面我们监听了本地8081端口,并且配置了/ping的接口,这个go程序启动后,访问https://ip地址:8081/ping就会返回pong的text,就这么简单,另外,为了能让这个程序常驻在后台,使用了"github.com/icattlecoder/godaemon"这个库,我们来启动他,在cmd中执行

go run main.go -d=true

然后在浏览器试试访问https://ip地址:8081/ping接口

啊,报警告了,这说明我们的证书有问题,不过我们已经将根证书埋入我们的系统信任列表中了啊,根据之前的理论,客户端拿着服务端带来的CA证书在本地受信任的CA证书列表中查找,并对比其公钥是否一致,一致则信任,不是吗?我们查看下server证书详细信息,省略部分不关注数据

Administrator@PC-20210427XPHC MINGW64 ~/Desktop/crt/crtDemo
$ openssl x509 -in rootca.crt -noout -text
Certificate:Data:Version: 1 (0x0)Serial Number:d9:a5:8c:82:6e:f7:a3:a1Signature Algorithm: sha256WithRSAEncryptionIssuer: C=cn, ST=sz, L=sz, O=dobefa, OU=it, CN=karl/emailAddress=a.karl.comValidityNot Before: Jan 28 07:46:36 2022 GMTNot After : Jan  4 07:46:36 2122 GMTSubject: C=cn, ST=sz, L=sz, O=dobefa, OU=it, CN=karl/emailAddress=a.karl.comSubject Public Key Info:Public Key Algorithm: rsaEncryptionPublic-Key: (4096 bit)Modulus:.......Exponent: 65537 (0x10001)Signature Algorithm: sha256WithRSAEncryption......Administrator@PC-20210427XPHC MINGW64 ~/Desktop/crt/crtDemo
$ openssl x509 -in server.crt -noout -text
Certificate:Data:Version: 1 (0x0)Serial Number:fe:52:f8:e2:bf:78:1d:60Signature Algorithm: sha256WithRSAEncryptionIssuer: C=cn, ST=sz, L=sz, O=dobefa, OU=it, CN=karl/emailAddress=a.karl.comValidityNot Before: Jan 29 09:35:55 2022 GMTNot After : Jan  5 09:35:55 2122 GMTSubject: C=cn, ST=js, L=sz, O=dobefa, OU=it, CN=karl server/emailAddress=test.server.comSubject Public Key Info:Public Key Algorithm: rsaEncryptionPublic-Key: (4096 bit)Modulus:.......Exponent: 65537 (0x10001)Signature Algorithm: sha256WithRSAEncryption.......

可以看到上面的server.crt证书的Issuer为rootca,是一致的

再来查看下rootca证书公钥和server证书的公钥

Administrator@PC-20210427XPHC MINGW64 ~/Desktop/crt/rootCrt
$ openssl x509 -in root2.crt -pubkey
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHRS1rCHo/DeXWQHvxHclhAkBT
as6VVbVFzf/tVjNHUsabKVnW6P+/ASQj+AoGgX+cjvX+6V44NcavJw8juokFrJki
MOZvt8wiY/kjsvMAZ8d1xTYYw0huUjMftFjemKJq7y6QFKrz+nqsJrsj1ThfFpfI
S3CAvnFMr9JtF+Uu8QIDAQAB
-----END PUBLIC KEY-----
................Administrator@PC-20210427XPHC MINGW64 ~/Desktop/crt/rootCrt
$ openssl x509 -in root3.crt -pubkey
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHRS1rCHo/DeXWQHvxHclhAkBT
as6VVbVFzf/tVjNHUsabKVnW6P+/ASQj+AoGgX+cjvX+6V44NcavJw8juokFrJki
MOZvt8wiY/kjsvMAZ8d1xTYYw0huUjMftFjemKJq7y6QFKrz+nqsJrsj1ThfFpfI
S3CAvnFMr9JtF+Uu8QIDAQAB
-----END PUBLIC KEY-----
-----BEGIN CERTIFICATE-----
................

发现也是一样的,那么还有哪边会有问题呢,我们看了google的提示信息,然后不妨看看百度的证书

这边有个重要的信息,即使用者可选名称,里面配置了好多DNS Name,还有通配符,而我们的证书是没有的,这就是关键了,其他的参数没有暂时还不影响我们的证书,所以我们来看看如何添加这个到我们的证书中

这个字段我们查到其对应的是“Subject Alternative Name”这个扩展字段,还记得我们在签发服务器证书的时候,使用的x509模块,该模块支持-extensions和-extfile来配置一个扩展字段,我们先建立一个配置文件ssl.cnf文件,内容如下

[ req_ext ]
subjectAltName = @alt_names[alt_names]
IP.1    = 10.0.10.22
#DNS.1   = your-website.dev
#DNS.2   = another-website.dev

因为我们是使用的IP访问的,所以我们添加了一个IP.1 = 10.0.10.22的alt name

然后执行签发命令,带上配置文件

Administrator@PC-20210427XPHC MINGW64 ~/Desktop/crt/crtDemo
$ openssl x509 -req -in server.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -out server.crt -days 36500 -extensions req_ext -extfile ssl.cnf
Signature ok
subject=/C=cn/ST=js/L=sz/O=dobefa/OU=it/CN=karl server/emailAddress=test.server.com
Getting CA Private Key

确认一下我们的新的证书

$ openssl x509 -in server.crt -noout -text                                      Certificate:Data:Version: 3 (0x2)Serial Number:fe:52:f8:e2:bf:78:1d:61Signature Algorithm: sha256WithRSAEncryptionIssuer: C=cn, ST=sz, L=sz, O=dobefa, OU=it, CN=karl/emailAddress=a.karl.comValidityNot Before: Jan 30 03:27:04 2022 GMTNot After : Jan  6 03:27:04 2122 GMTSubject: C=cn, ST=js, L=sz, O=dobefa, OU=it, CN=karl server/emailAddress=test.server.comSubject Public Key Info:Public Key Algorithm: rsaEncryptionPublic-Key: (4096 bit)Modulus:.........Exponent: 65537 (0x10001)X509v3 extensions:X509v3 Subject Alternative Name:IP Address:10.0.10.22Signature Algorithm: sha256WithRSAEncryption....................

可以看到X509v3 extensions: X509v3 Subject Alternative Name: IP Address:10.0.10.22已经配置到证书里面了,我们部署到go服务上,再来访问下浏览器试试吧

使用

taskkill /f /t /im main.exe

来关闭服务器进程,然后重新启动go服务,访问接口

这样就成功了,我们的证书已经被浏览器信任了。

使用自签证书利用浏览器进行HTTPS接口的安全访问相关推荐

  1. RedHat/CentOS8【OpenSSL】制作自签证书和 HTTPS 配置

    1.OpenSSL 制作自签名证书 1.1.第一阶段:制作 CA 根证书 1.2.第二阶段:制作服务器证书 1.3.第三阶段:制作客户端证书(双向认证使用) 2.Web 容器配置 HTTPS站点 2. ...

  2. Windows下使用OpenSSL生成自签证书(亲测)

    一,前言 经常写博客的小伙伴儿都知道,大家一般在前言里面会提到为什么写这篇博客,而我这篇博客 主要是探讨OpenSSL自签名证书,用于对安全性要求比较高的商业活动.. 二,探讨前景: 生成一对 RSA ...

  3. openssl实现CA自签证书和颁发数字证书

    1. 测试环境准备: CA签署服务器:192.168.2.181 WEB服务器:192.168.2.180 CA安装openssl  WEB服务器使用nginx 2. CA生成自签证书: 2.1 为C ...

  4. CA自签证书的颁发及应用

    1.首先安装openssl软件和ssl模块 [root@localhost ~]# yum install openssl [root@localhost ~]# yum install mod_ss ...

  5. 利用浏览器调试功能 计算 百度网盘 文件数量 V2

    最近需要统计百度网盘里文件的数量,百度网盘又没有提供这样的功能,因此之前自己写了段脚本进行查验,见<利用浏览器调试功能 计算 百度网盘>.之后发现每个目录最多文件数只有1000,因此研究了 ...

  6. 浏览器证书基础介绍和如何测试本地浏览器的HTTPS的完备性

    最近一个项目是更新浏览器证书,这篇文章写给有相关需求的工程师. 1 首先,了解证书的基本原理和工作方式,然后了解证书的更新办法, 1 其次,最好是,如何去验证这些证书. 1 证书的基础知识: HTTP ...

  7. 记录一下CA自签证书如何生成(linux环境下一般为部署到nginx)

    首先前端是部署在nginx上的嘛,那你部署https肯定就要证书,这里记录一下如何自签证书 (ps:这是我自己记录的,不是网上随便cv搬的,我自己用是可用的,成功不了看看是不是自己代码输错了) 一.生 ...

  8. 利用浏览器指纹技术进行防恶意点击和恶意骚扰刷新系统

    本程序采用php语言自主开发,利用浏览器指纹技术进行防恶意点击和恶意刷新检测,抓取设备信息,准确无误! 自主开发完整设备信息追踪系统,用于控制关键词发包排名点击数据,防恶意访问,数据监控,用户行为检测 ...

  9. 小实验:利用wireshark解密https

    写的不够全面,甚至会有错误,会慢慢补全相关内容,欢迎大家在评论区友好交流,批评指正. 小实验:利用wireshark解密https 一.实验过程 1.配置系统用户环境变量 2.配置Wireshark工 ...

最新文章

  1. 人体姿态估计研究文集
  2. mysql创建表选择字段的时候下尽量小
  3. 制定规则者与打破规则者
  4. maven 不编译jasper文件_第一个SpringBoot项目、核心配置文件properties(yml、yaml)、集成jsp...
  5. mysql dba 试题_mysql dba面试题及答案.docx
  6. 12 Essential Bootstrap Tools for Web Designers
  7. 亚马逊与 Uber,软件开发的方式有何不同?
  8. pycharm 运行提示:@Error running ‘xx‘: Cannot run program “C:\Python27\python.exe“ (in directory “D:\...)
  9. mysql数据库实验4
  10. python语言程序设计实验题p181答案_2010年新版教材自考网络操作系统02335_复习笔记...
  11. 安科瑞【节能学院】电气火灾监控系统在太焦铁路博爱站房项目的应用
  12. 英特尔AI大会:新版AI芯片
  13. 关于tomcat中Host中appBase与docBase的关系
  14. MacOS清理DNS缓存的终端代码推荐
  15. 系统镜像ISO、GHO、WIM、ESD的区别
  16. cas4.0实现多种方式邮箱/手机号码登录及认证
  17. python好学吗 老程序员-学习python,难道是为了当一名苦逼的程序员吗?
  18. 与或非门——python逻辑电路
  19. Linux以太网卡软硬件架构
  20. android清理存储工具,(安卓)CCleaner Pro — 手机垃圾文件清理工具

热门文章

  1. Android层面上对sensor及event事件的处理
  2. 小而美的城市,比鸭脖更诱人
  3. 用C语言编写5个学生,每个学生有3门课程成绩,从键盘输入学生数据(学号,姓名,3门成绩)计算平均成绩,将成绩放入磁盘文件stud中
  4. C DoEvents
  5. java scp发送文件到服务器,Java实现往远程服务器传输文件
  6. Python:对多角星的绘制
  7. Kubeedge 1.5 部署指南
  8. python练习题19:四叶玫瑰数
  9. 判断一个数是否为四叶玫瑰数
  10. 【秃头系列】-【本科生毕设论文格式Word】自动生成目录并调整目录