likes
comments
collection
share

告诉老默,我想用HTTPs了

作者站长头像
站长
· 阅读数 16

目录

  1. 引言
  2. 什么是HTTPs
  3. 自制证书
  4. 服务端开启HTTPs
  5. 后记

1. 引言

多年以后,面对绿盟科技的技术面试官,程序猿小❤将会回想起黑客 Tom 带他见识网络防火墙瞬间被瓦解的那个遥远的下午。

“全球施工队,在任何地方,任何时候,都会将 ‘安全’ 放在第一位!而网络项目安全,又是互联网产品的重中之重,那么,你能说一下项目开发中的数据传输如何保证安全性吗?”

不及回想,只听到面试官慢条斯理的问道。

“呵,施工队,作为新时代农民工我当然知道安全第一。万万不能一边施工,一边吃鱼!”此时,我本想胡诌乱扯一通,不过对面是一个笑脸盈盈的面试官,不好拒绝,于是我思考一刻缓缓答到:“我们在项目开发上线的时候,为了接口数据传输的安全,访问可能需要用到 HTTPs”。

这时就有小伙伴产生疑问了,数据安全访问,不是用 POST 的请求方式就可以了吗?

事实当然并非如此,“我们在接口设计的过程中,GET 请求的访问安全性最差,因为传输的数据会拼接在 URL 中直接发送,而 POST 请求会把传输的数据放到 Body 体中,在地址栏不可见,但两者在传输过程中没有区别。要想达到安全传输数据的目的,还得使用 HTTPs 的方式”。

2. 什么是HTTPs

2.1 HTTPs简介

“那你说说对 HTTPs 的理解吧”,面试官对这个回答似乎不是很意外,于是再度问道。

“网络中,HTTP 协议的通信无处不在,熟知 RESTful API 开发的程序猿都知道,即便是 POST 请求,在网络传输时由于明文传输等原因,依旧不是很安全。这时,就需要用到 HTTPs,通俗来讲 HTTPs = HTTP + 数据加密 + 身份认证 + 完整性保护。”

HTTPs 的实质就是在 HTTP 应用层和 TCP 传输层之间新增了一层,假设我们使用 TLS 协议来进行 HTTPs 加密,那 HTTPs 就是 HTTP 先与 TLS 通信,再由 TLS 和 TCP 通信

2.2 加密过程

告诉老默,我想用HTTPs了

我接着说:“HTTPs 加密大体分为两个阶段,分别是证书验证数据传输阶段,它们的交互过程如下:“

2.2.1 证书验证过程

1)浏览器发起 HTTPs 请求;

2)服务端生成一对公私钥,私钥由服务端自己存储,公钥放在 HTTPs 证书里返回给客户端, 证书内容还包含网站地址、证书颁发机构、失效日期等;

3)客户端验证证书的合法性(比如证书中的网址和当前网址是否一致,证书是否过期),若不合法则提示告警;

2.2.2 数据传输阶段

1)当证书验证合法后,客户端生成一个随机数作为对称算法的密钥;

2)客户端通过公钥加密随机数,并传送到服务端

3)服务端接收到加密后的随机数以后,通过自己的私钥对随机数进行解密;

4)服务端拿到对称密钥(随机数)以后,对返回的结果数据进行对称加密。

3. 自制证书

“好的,那如果让你设计一个 HTTPs 的服务器,你会怎么做呢?”面试官似乎还想听到更多实战的经历,于是又接着问道。

我也不甘示弱,于是又说:“明白了 HTTPs 的原理及验证流程以后,我们梳理一下开启 HTTPs 安全通信时必备的三样东西:CA 证书、服务器证书以及服务器私钥。”

  1. CA(Certification Authority)证书由 CA 机构颁发,用来证明某个实体身份的合法性;
  2. CA 证书需要安装在客户机器,也就是浏览器上,用来验证服务器证书的真实性;
  3. 服务器的证书用来发送给客户端,服务器私钥做数据加解密。

“所以,我们要开启一个 HTTPs 服务时,需要先申请证书,自制证书通用软件有两款:OpenSSL 和 XCA。前者是命令行界面,后者是图形界面,为了保证过程可视化,我们可以使用 XCA 来制作证书。”

3.1 使用 XCA 制作证书

这时,聪明细心的读者可能会发现:如果面试官要看我申请证书,那时间显然就不够了!但是,为了让阅读者更好的熟知 HTTPs 加密过程,贴心的程序猿小❤面试完毕后梳理了如下流程:

首先,下载安装 XCA工具,下载地址:xca.hohnstaedt.de/,我这里下载的最新 XCA 2.4.0 版本

1)安装完成以后,我们打开 xca 软件,点击主页面的 文件 -> 新建数据库(选择证书申请的存储目录,再输入密码)

告诉老默,我想用HTTPs了

2)切换到证书页面,点击创建证书(我已经创建过证书,所以在证书栏已经存在,请忽略)

告诉老默,我想用HTTPs了

3)在来源页面,分别选择签名、算法和模板,最后点击 “应用模板所有信息”

告诉老默,我想用HTTPs了

4)切换到主体页面,填写证书内部名称,其余选项可随便填写,最后生成新密钥

告诉老默,我想用HTTPs了

5)点击创建,OK 返回,在新生成的证书上创建证书【注意:选择签名时选择“使用此 CA 证书进行签名”,由于我们现在是申请服务端证书,所以选择模板时选择 默认TLS_server】

告诉老默,我想用HTTPs了

6)再次切换到主体,填写名称等信息,点击生成新密钥,创建完成后 OK 返回

告诉老默,我想用HTTPs了

这时,CA 证书和服务器证书就创建完成了,接下来导出。

3.2 导出证书

1)在证书页面,导出 CA 证书

告诉老默,我想用HTTPs了

2)导出服务端证书

告诉老默,我想用HTTPs了

3)在私钥页面,导出服务端私钥

告诉老默,我想用HTTPs了

至此,我们使用 XCA 生成证书完毕,接下来在服务端使用证书和私钥开启 HTTPs

4. 服务端开启HTTPs

这里示例用的是 Golang 语言,其它语言类似,只需要在 HTTP 做服务监听时切换成 HTTPs 即可。

Go 语言控制 HTTPs 是否打开时,可在项目启动的入参新增三个参数控制:

safeMode := flag.Bool("safe_mode", true, "https mode")
certPath := flag.String("cert_path", "D://runSpace//wecom//ca//server.crt", "server ca")
keyPath := flag.String("key_path", "D://runSpace//wecom//ca//server.pem", "private key")

1)如下图所示

告诉老默,我想用HTTPs了

2)safeMode 控制 HTTPs 是否打开

告诉老默,我想用HTTPs了

日志如下

[GIN-debug] Listening and serving HTTPS on :80

3)启动完成后,可以在浏览器输入 https://127.0.0.1:80 访问

告诉老默,我想用HTTPs了

由于未在浏览器添加 CA 证书,所以访问时会提示,我们选择【高级->继续前往】即可。

4)如果不想每次访问都报这类提示,我们可以在浏览器添加刚才申请的 CA 证书,谷歌浏览器导入过程如下

告诉老默,我想用HTTPs了

5)【管理证书 -> 导入】导入刚才在 XCA 申请的证书,关闭浏览器重启即可

告诉老默,我想用HTTPs了

至此,HTTPs 服务就可以正常访问了。如果想切换为 HTTP 访问,只需要把命令行参数 safe_mode 置为 false 即可。

完整代码在 GitHub 可见

5. 后记

面试官微微点头,又问到:“HTTPs 加密的过程中,为什么私钥认证和数据传输,分别用了非对称加密和对称加密两种方式呢?”

我狡黠一笑,给面试官挖了无数次坑,他们果然都自愿踩上来了:“这当然是由它们两者的特点决定的,其中:”

  • 对称加密:即信息的双方用同一个密钥去加解密信息,使用了对称密码编码技术。由于算法公开,所以密钥不能对外公开。它的计算量小,加密速度快。缺点是不安全,密钥管理困难,如 AES,IDEA。
  • 非对称加密:只能由成对的公私钥进行加解密,一般是公钥加密,私钥解密。过程:甲方生成一对密钥,并将其中一把作为公钥公开出去;乙方拿到公钥,对数据加密后发送给甲方,甲方用专用私钥进行解密。安全,但加密速度较慢,如 RSA 算法。

“HTTPs 加密时使用了混合加密,结合了对称加密和非对称加密的优点,将对称加密的公钥通过非对称加密传输。这样,既保证了公钥传输过程的安全性【非对称加密】,也保证了数据交换时的高效性【对称加密】。”

面试官微微点头,“嗯嗯,这个问题先到这,接下来......”。有了良好的开头,面试过程中我腿也不抖了,嘴也不哆嗦了,HTTPs 也不想学了,晚上喊上老默一起吃鱼吧! emmm 真是美好的一天啊~~