HTTPS实战全纪录:如何自制证书

2019/8/9 10:25:00

虽然有很多途径可以申请到免费的证书,但一般都是单域名(不支持泛域名),限制太多,本地调试极不方便,所以我们希望本地开发时能够使用我们自己签发的证书。下面我们就来自己实践一下如何从头开始自制HTTPS证书。
 
证书一般都是用openssl来生成,当然也可以用jdk自带的keytool来生成,但是最终还是要用openssl来转换格式,所以一般还是推荐用openssl来生成。
 
3.1.2.1. 安装openssl
首先当然还是安装openssl,这里我们只介绍Windows平台,Linux系统的请参考这里,点击这里下载Win64位的安装包:
 
 
安装很简单,安装完毕之后为了使用方便,建议配置一下环境变量:
 
 
然后就可以随时随地执行openssl命令了。
 
3.1.2.2. 生成CA根证书
我们先生成一个自己的CA根证书ca.crt,然后再用这个根证书生成服务端证书server.crt,有人会问,为啥不直接生成服务端证书呢?因为这样做的话将来我们只要导入一个CA根证书,其它所有用它生成的证书都默认是可信任的,方便嘛!
 
好了,说了这么多废话,下面开始了:
 
# 生成CA私钥
openssl genrsa -out ca.key 1024
# 生成CA根证书,-day指定证书有效期
openssl req -new -x509 -key ca.key -out ca.crt -days 365
就这么简单,第二步需要输入几个东西,虽然说乱填也可以,但建议按照提示来填,其中Common Name需要特别注意,如果是生成CA证书的话,可以输入诸如My CA之类的,如果是生成服务端证书的话,必须输入网站的域名,可以输入泛域名,如*.haoji.me
 
 
另外,如果报了unable to write 'random state'的错误,一般都是因为没有使用管理员权限打开命令行窗口。
 
3.1.2.3. 生成服务端证书
CA证书的生成不同的时,我们需要先生成一个csr证书请求文件文件(CSR,Cerificate Signing Request),有了这个文件之后再利用CA根证书生成最终的证书:
 
# 生成服务端私钥
openssl genrsa -out server.key 1024
# 生成证书请求文件
openssl req -new -key server.key -out server.csr
# 生成最终证书文件,-day指定证书有效期
openssl x509 -req -days 365 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
操作截图:
 
 
但!是!各位看官先别急着去实践,以上证书我在Chrome55下测试没问题,但是Chrome61下测试提示Subject Alternative Name missing错误:
 
The certificate for this site does not contain a Subject Alternative Name extension containing a domain name or IP address.
 
提示必须指定DNS Name或者IP地址,而指定这个必须要用v3的证书。生成v3证书只需要比上面多加2个参数-extfile openssl.cnf -extensions v3_req,但是多了一个额外的配置文件,这个文件里面可以填很多东西(完整配置文件参考这里),我们这里仅仅需要指定subjectAltName即可。
 
先准备一个名为openssl.cnf的文件,内容如下:
 
[v3_req]
subjectAltName = @alt_names
 
[alt_names]
DNS.1 = localhost.com
DNS.2 = www.localhost.com
DNS.3 = www.test123.com
#IP.1 = 127.0.0.1
解释一下,这里的alt_names指的是最终可以访问的域名或者IP,所以,其实一个证书是可以多个网站同时使用的。被访问域名只要满足DNSIP中的一个,其证书就是合法的。
 
然后再来重新生成证书,为了对大家产生误导,我们再来一遍完整的过程:
 
# 生成服务端私钥
openssl genrsa -out server.key 1024
# 生成证书请求文件
openssl req -new -key server.key -out server.csr
# 生成最终证书文件,-day指定证书有效期
openssl x509 -req -days 365 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -extfile openssl.cnf -extensions v3_req -in server.csr -out server.crt
双击生成的证书可以看到如下内容:
 
 
3.1.2.4. 生成客户端证书
如果需要实现HTTPS双向认证,还要按照上述服务端一模一样的操作再生成一个client.crtclient.key,这里我们就不重述了,90%的场景都是不需要双向认证的。
 
3.1.2.5. Windows导入证书
上述步骤执行完之后生成了如下文件:
 
 
我们只需要双击ca.crt导入这个自制根证书即可,以后只要是利用这个证书生成证书浏览器都会认为是可信任的,这让我想起了12306干的勾当,如果你能把你这个根证书推广到全世界的电脑和手机,那么你也可以成立一家CA公司专门卖证书了,哈哈。
 
导入的时候注意证书存储位置:
 
 
由于这是很敏感的操作,所以操作系统一定会有警告:
 
 
3.1.2.6. Mac导入证书
双击ca.crt,会要求输入密码,输完密码就会导入证书,双击导入完的证书,选择始终信任即完成根证书的导入并信任: