司开星的博客

私有接口添加HTTPS私有证书及客户端验证

本文主要研究给私有接口添加自签名证书并验证客户端真实性。

服务器证书

生成私有证书

要生成证书首先要有个私钥:

openssl genrsa -out ssl.key 2048

之后生成证书请求:

openssl req -new -key ssl.key -days 3650 -out ssl.csr

其中days参数是证书有效期.

此时需要填一些资料, 作为证书信息。 不过除了Common Name需要填实际域名或IP外, 其他的可以随便填。

最后生成的ssl.csr就是证书请求了。 一般来说证书请求是发给公开CA签名, 但私有接口就没必要去找它们签名了。

可以直接用自己的私钥签名刚刚生成的证书请求:

openssl x509 -req -in ssl.csr -signkey ssl.key -out ssl.crt

不过如果需要签更多证书请求或者要使用CA证书的话, 就需要自己生成私有CA证书:

openssl x509 -req -in ssl.csr -extensions v3_ca -signkey ssl.key -out sign.crt

用CA证书给自己的证书请求签名:

openssl x509 -req -in ssl.csr -extensions v3_usr -CA sign.crt -CAkey ssl.key -CAcreateserial -days 3650 -out ssl.crt

这样就得到了服务器端的私有密钥ssl.key和数字证书ssl.crt, 部署在服务器程序上即可。

客户端信任证书

上面得到的证书是私有证书, 客户端默认只信任公开CA签名的证书。要让客户端信任私有证书需要做一些操作。如果客户端是浏览器, 直接根据浏览器的步骤信任证书即可。

笔者使用的客户端是Python中的requests模块, 信任证书需要在发起请求时添加verify参数, 值为证书的CA_BUNDLE,它可以在服务器端生成, 不过要传给客户端比较麻烦。笔者直接使用firefox浏览器导出证书(x.509含链证书), 并在请求时添加即可:

requests.get('https://exaple.com', verify='ca.crt')

验证客户端请求

HTTPS虽然也有验证客户端证书的方式, 但为每个请求的客户端配置证书比较麻烦, 且也不是所有服务器程序都支持验证客户端证书。公开API一般使用Token认证的形式,不过如果对私有接口安全性要求高可以在此基础上多加一个TOTP验证,算法也可以在已有的基础上自行修改,本文对此就不再赘述。

参考资料:

  1. 科普:TLS、SSL、HTTPS以及证书
  2. 基于OpenSSL自建CA和颁发SSL证书
  3. OPENSSL中通过CRT生成ca-bundle证书链