一、背景

随着安全需求的发展,现在几乎所有的第三方应用都要求回调地址是https协议的,而且很多微服务软件部署的时候,也会要求内网之间的通信也用https协议,这就导致我们在本地开发的时候很不方便,有没有什么办法解决呢?

有的,兄弟,有的!

二、原理

在讲解如何本地创建证书和信任ca之前,先来简单说说原理。
大家都知道,http协议是明文传输,所以,网络中间的任何人都可以知道其中的内容,当然也可以篡改,例如:到达客户端的网页被莫名其妙被注入广告。
既然明文会被中间人查看和篡改,聪明的你肯定立马想到,把内容加密不就解决了。
这里就要提到两种加密方式:

1. 对称加密:

顾名思义,对称指的就是加密和解密用的密钥相同,它的特点是加解密速度很快,但也导致很容易破解。
在这里插入图片描述

2. 非对称加密:

既然和上面有区别,它的加密解密自然就使用不同的密钥。这里大家只需要知道它的效果是:私钥(服务端用)加密的内容只有公钥(客户端用)能解,公钥加密的内容只有私钥能解就够了,它的特点是虽然安全,但加密解密速度慢。
聪明的你,立马又想到了:
(1) 服务端只需要先把公钥发给客户端,私钥在自己手里,这样客户端加密的内容,中间人就解不了了
(2) 再结合一下对称加密:客户端拿到公钥后,回给服务端一个对称加密用的密钥,服务端后续用对称密钥加密内容,这样中间人也解不了服务端的内容了,安全又高效。
兄弟,6啊!
但中间人也有新的办法截获信息。
在这里插入图片描述

从上图可以发现,加密算法并不能解决传递密钥的安全问题,机智的中间人总可以获取通信内容,理解了这个,那么恭喜,兄dei,你掌握了https抓包的原理
同时也引出了下一个问题:如何安全传递密钥呢?

3. CA

CA的全拼是:Certification Authority,可以译为证书颁发机构
浏览器内会预置一些信任机构,用以校验证书是否可信。既然有自动信任的机构,当然也可以手动添加信任机构或信任证书了,这就是后面我们用来使用自签名证书的原理。
在这里插入图片描述

通过引入CA,可以看到,客户端有了校验公钥的能力,随后就可以在传递对称密钥后,开始加密通信了。

这里想提一下12306,不知道大家还记得不,早期访问会提示不安全:
在这里插入图片描述
原因就在于12306使用的证书是“自签名”的,它CA不被浏览器默认信任,感兴趣的话可以搜搜。

三、生成自签名证书

1. 准备工作

这里使用的是cfssl来创建自签名证书,下载自己平台支持的即可,这里我选的是windows,需要用到两个软件

  • cfssl.exe
  • cfssljson.exe

免积分下载地址

记得把文件路径添加到系统PATH中,否则cmd中无法识别相关命令。

2. 创建并信任CA

2.1 创建并生成ca相关文件

ca-csr.json

{
    "CN": "Local Root CA",
    "key": {
        "algo": "rsa",
        "size": 4096
    },
    "names": [{
        "C": "CN",
        "ST": "Beijing",
        "L": "Beijing",
        "O": "Example Co",
        "OU": "PKI"
        }],
    "ca": {
        "expiry": "87600h"
    }
}

解释相关配置含义:

  • CN:(Common Name)根 CA 的名称。
  • key:加密算法。
  • names:
    • C:Country,国家代码(例如 CN、US)
    • ST:State/Province,省/州
    • L:Locality,城市
    • O:Organization,组织名称(公司或机构)
    • OU:Organizational Unit,部门或单位
  • ca.expiry:根 CA 证书有效期(示例为10年,87600小时)。

生成根CA证书

cfssl gencert -initca ca-csr.json | cfssljson -bare ca

输出文件:

  • ca.csr(根 CA 的 CSR)
  • ca-key.pem(根 CA 私钥)
  • ca.pem(根 CA 证书)

由于windows无法识别pem格式的证书,把ca.pem复制并更改类型改为crt,如下图所示:
在这里插入图片描述

2.2 信任自建的根CA

双击ca.crt进行安装:安装证书 -> 本地计算机 -> 将所有的证书都放入下列存储 -> 浏览 -> 受信任的根证书颁发机构。
在这里插入图片描述
在这里插入图片描述
至此就会提示完成,相关窗口点完成或确认至退出即可。

2.3 验证查看根证书是否安装完成

在运行中输入:certlm.msc
然后在弹出的窗口左侧:受信任的根证书颁发机构 -> 证书,找到刚安装的自建证书即可。
在这里插入图片描述
在这里插入图片描述
至此,我们就创建好了ca,可以为其他网站签名证书了。

3. 为本地开发的域名签发证书

3.1 准备签发策略配置

ca-config.json

{
  "signing": {
    "default": {
      "expiry": "87600h",
      "usages": ["signing", "key encipherment", "server auth", "client auth"]
    }
  },
  "profiles": {
    "server": {
      "expiry": "87600h",
      "usages": ["signing", "key encipherment", "server auth", "client auth"]
    }
  }
}
3.2 准备申请网站的配置并生成证书

这里我们模拟一个百度的单点登录中心,拟申请的域名是sso.baidu.com
server-csr.json

{
  "CN": "sso.baidu.com",
  "hosts": [
    "sso.baidu.com"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "Example Co",
      "OU": "SSO"
    }
  ]
}
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem  --config=ca-config.json -profile=server server-csr.json | cfssljson -bare server

输出文件:

  • server.csr(CSR)
  • server-key.pem(私钥)
  • server.pem(证书)
    在这里插入图片描述
    读到这里,细心的你可能会发现,之前说的是公钥私钥,怎么到这里公钥不见了,取而代之的出现个证书
    是的,公钥并没有以单独的文件形式存在,它其实存在了证书里。证书中除了公钥外,还有很多额外信息:颁发者、颁发对象、有效期等(参考上面12306的证书截图)。由于已经懂得了HTTPS的大致原理,感兴趣的话可以自行了解实际细节,这里不再赘述了。

四、验证自签名证书

1. 修改hosts,使模拟域名指向本机

windows的hosts文件在:C:\Windows\System32\drivers\etc
记事本要使用管理员权限打开,否则无法保存。
在这里插入图片描述

2. 使用自签名密钥启动server

这里使用tornado来启动一个简易服务,当然你也可以用nginx等软件。代码如下:
main.py

import tornado.web
import tornado.ioloop
import tornado.httpserver

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, HTTPS world!")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    ssl_options = {
        "certfile": "server.pem",      # 证书文件
        "keyfile": "server-key.pem",   # 私钥文件
        # "ca_certs": "ca.pem",        # 可选,若需双向认证或客户端校验
    }

    app = make_app()
    server = tornado.httpserver.HTTPServer(app, ssl_options=ssl_options)
    server.listen(4433)  # 监听 4433 端口,非 443 方便测试
    print("HTTPS server started on https://sso.baidu.com:4433")
    tornado.ioloop.IOLoop.current().start()

安装tornado

pip install tornado

启动服务

python main.py

3. 浏览器验证

在这里插入图片描述

Logo

纵情码海钱塘涌,杭州开发者创新动! 属于杭州的开发者社区!致力于为杭州地区的开发者提供学习、合作和成长的机会;同时也为企业交流招聘提供舞台!

更多推荐