前置知道

○OpenSSL是为实现SSL和TLS提供支持的工具包;
○HTTPS证书只能绑定域名而不能绑定某个IP;
○1.1.1版本OpenSSL命令用法的官方文档
○操作环境:

1
2
3
Windows 10
openssl 1.1.1(通过"openssl version"命令查看);
nginx 1.17.1

操作步骤

添加本地域名

●定义本地域名以”blog.congzhou.com”为例,将域名解析添加到“Windows\System32\drivers\etc”下的hosts文件,hosts文件中的域名不支持通配符;

1
127.0.0.1 blog.congzhou.com

生成HTTPS所需私钥与证书

●执行如下命令创建本地模拟CA的私钥与CA根证书,分别生成”RootCA.key”和”RootCA.pem”两个文件,其中用到的国家编码在这里

1
2
3
4
5
6
7
8
9
10
11
12
13
openssl req -x509 -nodes -new -days 365 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=CN/CN=YCZ-Root-CA"

/******
* 命令解读
* openssl-req主要用于创建与处理证书请求(CSR, certificate signing request),也用于创建自签名方式的根证书
* 参数解读
* -x509: 输出证书而不是CSR
* -nodes: 生成的私钥不做加密
* -new: 当没有-key参数时将使用-newkey和-pkeyopt参数生成私钥
* -days: 证书有效天数,默认30天
* -newkey rsa:2048 : 生成2048bit长度的rsa格式私钥
* -subj: 设置证书涉及到的字段(称为证书的subject)值,/C是CountryName编码,/CN是CommonName即CA机构名称
****/

●执行如下命令生成上一步pem证书的对应crt格式的证书文件”RootCA.crt”,Windows中crt扩展名的证书文件右键菜单才有”安装”选项;

1
2
3
4
5
6
7
8
9
openssl x509 -inform pem -in RootCA.pem -out RootCA.crt

/******
* 命令解读
* openssl-x509用途较多,可用于转换证书格式和为CSR签名
* 参数解读
* -inform 输入证书的格式,取值为pem或der,默认值pem,pem是base64编码的文本格式,der是DER(Distinguished Encoding Rules)编码的二进制格式
* -outform 输出证书的格式,默认与输入整数的格式一致
****/

●执行如下命令创建本地域名网站私钥与网站证书req,分别生成”congzhou.key”和”congzhou.csr”两个文件,这里将证书签到域名”*.congzhou.com”方便以后也可以给其他二级子域名使用;

1
2
3
4
5
6
7
8
9
10
openssl req -new -nodes -newkey rsa:2048 -keyout congzhou.key -out congzhou.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=Example  Company Limited/CN=*.congzhou.com"

/******
* 参数解读
* -new: 生成一个新的CSR
* -subj参数使用到的subject含义:/ST是StateOrProvinceName,/L是Locality,/O是Organization。/CN用于网站时就是网站的域名,支持"*.example.com"形式的通配符,但只能填写一条
*
*
* Subject Alternative Name(简称SAN,也称"使用者备用名称")用于弥补CN数量的限制,并会在将来逐渐替代Common Name,而且Chrome版本58及以上已经将SAN作为证书校验项,缺少SAN报“Subject Alternative Name Missing”错误
****/

●创建包含SAN等证书扩展信息的congzhou.ext文件,文件内容如下;

1
2
3
4
5
6
7
8
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.congzhou.com
DNS.2 = localhost

●使用CA证书”RootCA.pem”文件及证书扩展信息”congzhou.ext”文件给网站证书签名生成证书到”congzhou.crt”文件;

1
2
3
4
5
6
7
8
9
10
openssl x509 -req -days 1024 -in congzhou.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile congzhou.ext -out congzhou.crt

/******
* 命令解读
* openssl-x509用途较多,此处用于为CSR签名
* 参数解读
* -req 指明此处x509命令用于为CSR签名
* -CAserial 无须通过-set_serial手动指定serial number
* -extfile 指定CA扩展信息所在文件
****/

添加对CA证书的信任

♂方式1:在”RootCA.crt”文件的右键菜单选”安装证书”,”证书存储”选择”受信任的根证书颁发机构”;
♂方式2:运行”certmgr.msc”,在左侧“受信任的根证书颁发机构->证书”上右键菜单“所有任务->导入”选择RootCA.crt文件安装;
♂安装成功后在”certmgr.msc”证书管理程序中可以看到刚刚创建的本地模拟CA信息;

本地网站使用证书

♀使用证书,以nginx为例,server段添加如下内容:

1
2
3
4
5
6
server_name blog.congzhou.com;
listen 443 ssl; # ssl指定使用https

ssl_certificate "/certificate_path/congzhou.crt"; # 网站证书
ssl_certificate_key "/certificate_path/congzhou.key"; # 网站证书对应私钥
... ...

结果验证

▲验证1:访问本地https网站,浏览器校验通过;

▲验证2:浏览器中点开证书详情,可以看到颁发者、使用者信息,其中的SAN在”使用者可选名称”字段;

参考文献

How to Create Trusted Self-Signed SSL Certificates and Local Domains for Testing
How to create an HTTPS certificate for localhost domains
Solve Errors: “Subject Alternative Name Missing” “NET::ERR_CERT_COMMON_NAME_INVALID”
What is the SSL Certificate Common Name