制作一份可以被信用的自签名ssl证书
之前有写过一篇简单介绍ssl制作的证书:简单的制作ssl证书,并在nginx和IIS中使用
但是只是简单的制作,发现有个问题,就是哪怕添加到受信任的根证书下也不能被浏览器信任,所以现已重新整理一般可以被浏览器信任的证书制作方式。
首先,我们需要知道,ssl证书可以分为三种类型:根证书、中间证书、服务证书,而证书之间是一种链式结构,使用根证书签署生成中间证书,使用中间证书签署生成服务证书,服务证书提供给应用使用,而根证书和中间证书需要被系统添加到信任列表中。当然,中间证书可以有很多个,也就是中间证书可以签署生成另外一个中间证书,服务证书也可以认为是中间证书的最后一个节点。所以首先我们需要一个根证书,然后一步步签署得到服务证书。
制作根证书
1. 生成根私钥root.key,如果不支持RSA:2048,那么可以使用RSA:1024
1 | openssl genpkey -algorithm RSA:2048 -out root.key |
如果报错Algorithm RSA:2048 not found,那么可以使用这个命令生成私钥
1 | openssl genrsa -out root.key 2048 |
2. 使用根秘钥生成根证书请求root.csr
1 | openssl req -new -key root.key -out root.csr -subj "/C=CN/ST=China/L=Shenzhen/O=Example CA/OU=Software Root/CN=Example Root CA" |
这里-subj是证书的一些信息,如果不知道将会在命令执行后逐个输入:
1 | /C=表示两个字符的国家代码,CN表示中国 |
3. 使用一个临时文件记录拓展信息
1 | echo keyUsage = keyCertSign, cRLSign > .temp.ext |
4. 使用私钥和请求文件签署根证书root.crt,最后删除临时文件
1 | openssl x509 -req -days 36500 -in root.csr -signkey root.key -out root.crt -extfile .temp.ext |
其中-days表示有效期天数
到这里我们得到了根证书的三个文件:root.crt、root.csr、root.key。
制作中间证书
现在使用根证书root.crt、root.key来生成中间证书
1. 生成中间证书私钥intermediate.key,如果不支持RSA:2048,那么可以使用RSA:1024
1 | openssl genpkey -algorithm RSA:2048 -out intermediate.key |
如果报错Algorithm RSA:2048 not found,那么可以使用这个命令生成私钥
1 | openssl genrsa -out intermediate.key 2048 |
2. 使用中间证书秘钥生成中间证书请求intermediate.csr
1 | openssl req -new -key intermediate.key -out intermediate.csr -subj "/C=CN/ST=China/L=Shenzhen/O=Example CA/OU=Intermediate Web Security CA/CN=Example Web CA" |
上面-subj各参数的含义同根证书
3. 使用一个临时文件记录拓展信息
1 | echo keyUsage = digitalSignature, keyCertSign, cRLSign > .temp.ext |
4. 使用根证书签署生成中间证书intermediate.crt,最后删除临时文件
1 | openssl x509 -req -days 36500 -in intermediate.csr -CA root.crt -CAkey root.key -CAcreateserial -out intermediate.crt -extfile .temp.ext |
其中-days表示有效期天数
到这里我们得到了中间证书的三个文件:intermediate.crt、intermediate.csr、intermediate.key。
制作服务证书
首先,我们需要知道我们的证书可以使用的备选名称,也就是访问的域名或者IP地址,然后我们继续
1. 生成服务私钥server.key,如果不支持RSA:2048,那么可以使用RSA:1024
1 | openssl genpkey -algorithm RSA:2048 -out server.key |
如果报错Algorithm RSA:2048 not found,那么可以使用这个命令生成私钥
1 | openssl genrsa -out server.key 2048 |
2. 使用服务秘钥生成根证书请求server.csr
1 | openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=China/L=Shenzhen/O=Example CA/OU=Web Security/CN=example.cn" |
上面-subj各参数的含义同根证书
3. 使用一个临时文件记录拓展信息
1 | cat > .temp.ext <<EOF |
这里SubjectAlternativeName节点下可以理解为就是我们要信任的那些IP和域名,我们把我们需要的写上去就好了,我这边测试用192.168.139.128作为本地虚拟机上的地址验证
4. 使用中间证书签署生成服务证书server.crt,最后删除临时文件
1 | openssl x509 -req -days 36500 -in server.csr -CA intermediate.crt -CAkey intermediate.key -CAcreateserial -out server.crt -extfile .temp.ext |
注:这里我们也可以直接采用根证书来生成服务证书,只需要替换上面命令的中间证书和它的私钥即可
1 | openssl x509 -req -days 36500 -in server.csr -CA root.crt -CAkey root.key -CAcreateserial -out server.crt -extfile .temp.ext |
到这里我们得到了中间证书的三个文件:server.crt、server.csr、server.key。
证书应用
这里使用Nginx应用为例,比如我们修改Nginx的配置:
1 | server { |
重新加载Nginx配置,如果这个时候在未安装证书的时候直接访问,会提示不安全的提示。 
所以我们需要安装证书,如果服务证书直接由根证书签署,那么客户端只需要安装根证书(root.crt)即可,否则我们需要安装所有的根证书(root.crt)和中间证书(intermediate.crt)
1. 根证书安装在【受信任的根证书颁发机构】 
2. 中间证书安装在【中间证书颁发机构】 
3. 安装完成后,我们可以查看我们的服务证书(server.crt)的验证链是否正常(不正常会显示红叉)

然后我们再在浏览器打开我们的应用就可以被信任了 
注:如果证书正常,但是还是显示不安全,那么需要把浏览器全部关闭,重新打开浏览器即可
总结
最后总结一下,ssl证书验证过程是链式的,它会逐个验证每个中间证书,直至根证书,有一个验证不通过,则整个验证不通过,所以自签名证书一般只需要一个根证书即可,中间证书一般省略即可,这样只需要安装了根证书,未来我们只需要使用这个根证书签署芯德服务证书,在已经安装了根证书的客户端就可能直接使用了。
一个专注于.NetCore的技术小白
备注:
首先需要安装 OpenSSL 工具,下载地址 https://openssl-library.org/source/ ,本人安装的是 3.2.6
不安装 OpenSSL 工具,执行 openssl req -new -key intermediate.key -out intermediate.csr -subj "/C=CN/ST=China/L=Shenzhen/O=Example CA/OU=Intermediate Web Security CA/CN=Example Web CA" 命令会报错。
下面 linux 命令替换为 CMD 命令为:
1 | cat > .temp.ext <<EOF |