Skip to content

自签名证书生成

1. 简介

给自己的网站生成一个自签名证书,用于测试或者本地开发。自签名证书虽然不受浏览器信任,但在开发和测试环境中非常有用,可以帮助我们在本地环境中模拟 HTTPS 服务。

2. 使用 Docker 生成证书

使用 Docker 是最简单的方式,不需要安装额外的工具。下面的命令将使用 <soulteary/certs-maker> 镜像生成自签名证书:

bash
docker run -it \
    --rm \
    -e CERT_DNS="your.domain.com" \
    -v $PWD/certs:/ssl \
    soulteary/certs-maker:latest

该命令会在当前目录的 certs/ 文件夹中生成证书文件,包括 .crt 证书文件和 .key 私钥文件。

3. 在 Python 中使用自签名证书

3.1 创建 HTTPS 服务器

使用自签名证书创建 HTTPS 服务器,这里以 Sanic 框架为例:

python
from sanic import Sanic
from sanic.response import json

app = Sanic(__name__)
ssl = {
    "cert": "your.domain.com.crt",
    "key": "your.domain.com.key",
}


@app.route("/")
async def test(request):
    return json({"hello": "world"})


if __name__ == "__main__":
    app.run(host="your.domain.com", port=8000, ssl=ssl, dev=True)

上述代码创建了一个简单的 HTTPS 服务器,监听在 your.domain.com:8000 端口。

3.2 客户端请求

客户端在请求 HTTPS 服务时,需要指定证书文件来验证服务器:

python
import requests

r1 = requests.get("https://your.domain.com:8000", verify="your.domain.com.crt")
print(r1.json())

try:
    r2 = requests.get("https://your.domain.com:8000")
    print("Error: ", r2.status_code)
    print(r2.json())
except requests.exceptions.SSLError as e:
    print("Error:", e)

如果不指定 verify 参数,requests 会尝试使用系统的证书链验证,这会导致 SSL 错误,因为自签名证书不在系统的信任列表中。

3.3 使用 SSLContext

在 Python 中使用 SSLContext 来包装请求可以提供更多的控制选项:

python
import ssl
from ssl import SSLContext

context = SSLContext()
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_verify_locations(cadata="...")

通过 SSLContext,我们可以更精细地控制证书验证行为,包括:

  • verify_mode:设置证书验证模式
  • check_hostname:是否检查主机名
  • load_verify_locations:加载证书位置

4. 注意事项

使用自签名证书时需要注意以下几点:

  1. 仅用于开发和测试:自签名证书不应该用于生产环境,因为它们不受浏览器信任
  2. 证书安全:妥善保管私钥文件,不要泄露到版本控制系统中
  3. 域名匹配:证书中的域名需要与访问的域名完全匹配
  4. 有效期限:自签名证书通常有较短的有效期,需要定期更新

这样就可以在本地开发时使用 HTTPS 了。

5. 参考资料