[!NOTE]
对命令行不感兴趣的请直接使用 GUI 工具
GUI 证书工具:XCA
[!IMPORTANT]
数字证书密钥对
不同于SSH密钥对
数字证书密钥对 是
RSA PRIVATE KEY
使用openssl
SSH密钥对 是
OPENSSH PRIVATE KEY
使用ssh-keygen
数字证书密钥对 | SSH密钥对 | |
---|---|---|
程序 | openssl | ssh-keygen |
密钥文件 | -----BEGIN PRIVATE KEY----- | -----BEGIN OPENSSH PRIVATE KEY----- |
公钥文件 | -----BEGIN PUBLIC KEY----- | ssh-rsa |
证书文件 | -----BEGIN CERTIFICATE----- |
★ 生成密钥对
# 生成私钥
openssl genrsa -out foobar.prikey.pem [4096<密钥长度>]
# 生成加密私钥
openssl genrsa -aes256<加密算法> -out foobar.prikey.pem [4096<密钥长度>] [-passout pass:password]
# 私钥加密
openssl rsa -aes256<加密算法> -in foobar.prikey.pem -out foobar.prikey.pem
# 私钥减密
openssl rsa -in foobar.prikey.pem foobar.prikey.pem
# 生成公钥
openssl rsa -in foobar.prikey.pem -pubout -out foobar.pubkey.pem
★ 查看
# 查看私钥
openssl rsa -noout -text -in foobar.prikey.pem
# 查看公钥
openssl rsa -pubin -text -in foobar.pubkey.pem
# 查看证书签名请求
openssl req -noout -text -in foobar.csr.pem
# 查看证书
openssl x509 -noout -text -in foobar.crt
★ 创建证书签名请求
openssl \
req `#生成证书签名请求`\
-new `#使用新的签名请求`\
-utf8 `#utf8中文支持,默认ASCII`\
-newkey rsa:2048 `#即时生成私钥`\
-noenc `#私钥不加密`\
-keyout "foobar.prikey.pem" `#输出私钥文件`\
-subj\
\
/C=CN`# [Country Name]两位国家代码`\
/ST=四川`# [State or Province Name]州省`\
/L=成都`# [Locality Name] 县市`\
/O=公司名称`# [Organization Name] 组织名称`\
/OU=部门名称`# [Organizational Unit Name] 部门名称`\
/CN=使用者名`# [Common Name] 网站名、服务器名、使用者名`\
/[email protected]`# [Email Address] 邮箱地址`\
\
-out foobar.csr.pem
★ 签发证书
openssl x509 -req \
-days 3650 \
-sha256 \
\
-extfile openssl.cnf \
-extensions web \
\
-CA ca.crt \
-CAkey ca.prikey.pem \
\
-in foobar.csr.pem \
-out foobar.crt
★ 跳过证书签名请求直接签发证书
openssl \
req `#生成证书签名请求`\
-new `#使用新的签名请求`\
-x509 `#直接生成证书而不是签名请求`\
-utf8 `#utf8中文支持,默认ASCII`\
-days 3650 `#证书有效期`\
\
-newkey rsa:2048 `#即时生成私钥`\
-noenc `#私钥不加密`\
-keyout "foobar.prikey.pem" `#输出私钥文件`\
\
-CA ca.crt `#指定CA证书`\
-CAkey ca.prikey.pem `#指定CA私钥`\
\
-subj \
/C=CN`# [Country Name]两位国家代码`\
/ST=四川`# [State or Province Name]州省`\
/L=成都`# [Locality Name] 县市`\
/O=公司名称`# [Organization Name] 组织名称`\
/OU=部门名称`# [Organizational Unit Name] 部门名称`\
/CN=使用者名`# [Common Name] 网站名、服务器名、使用者名`\
/[email protected]`# [Email Address] 邮箱地址`\
\
-addext basicConstraints=critical,CA:FALSE \
-addext keyUsage=critical,digitalSignature,keyEncipherment \
-addext extendedKeyUsage=serverAuth,clientAuth \
-addext authorityKeyIdentifier=keyid \
-addext subjectKeyIdentifier=hash \
-addext subjectAltName=DNS:foobar.xxz.moe,DNS:*.foobar.xxz.moe \
\
-out foobar.crt
★ 证书格式转换
# .cer 转 .pem
openssl x509 -inform der -in foobar.cer -out foobar.pem
# .pem 转 .cer
openssl x509 -outform der -in foobar.pem -out foobar.cer
# 把客户端证书和私钥保存为.pem 格式
cat foobar.crt foobar.prikey.pem > client.pem
# 如需导出到 windows 供 P2S VPN 客户端使用, 需把客户端证书转换成.pfx 格式
openssl pkcs12 -export -inkey foobar.prikey.pem -in foobar.crt -out client.pfx -name "你的XX证书(或者其它友好名字,一般显示在软件里)"
★ Windows 软件签名
# Windows PowerShell 软件签名
(.\signtool.exe sign /tr http://timestamp.digicert.com /f "玉衡软件.pfx" /fd SHA1 exesign/*.exe) -and `
(.\signtool.exe sign /tr http://timestamp.digicert.com /as /f "玉衡软件.pfx" /fd SHA256 exesign/*.exe)
# 时间戳网站
http://timestamp.wosign.com/rfc3161
http://timestamp.digicert.com
★ 自用脚本
#! /bin/bash
cd "$(dirname "$0")"
if [[ $1 != "" ]];then
CN=$1
else
until [[ $CN != "" ]];
do
read -p "请输入名称[CN]:" CN;
done
fi
openssl \
req `#生成证书签名请求`\
-new `#使用新的签名请求`\
-x509 `#直接生成证书而不是签名请求`\
-utf8 `#utf8中文支持,默认ASCII`\
-days 365 `#证书有效期`\
\
-newkey rsa:2048 `#即时生成私钥`\
-noenc `#私钥不加密`\
-keyout "$CN.prikey.pem" `#输出私钥文件`\
\
-CA ../ca.crt `#指定CA证书,不指定CA生成的证书默认为CA证书`\
-CAkey ../ca.prikey.pem `#指定CA私钥`\
\
-subj /CN=$CN`# [Common Name] 网站名、服务器名、使用者名`\
\
-addext basicConstraints=critical,CA:FALSE \
-addext keyUsage=critical,digitalSignature,keyEncipherment \
-addext extendedKeyUsage=serverAuth,clientAuth \
-addext authorityKeyIdentifier=keyid \
-addext subjectKeyIdentifier=hash \
-addext subjectAltName=DNS:$CN.xxz.moe \
-out $CN.crt
★ 安装根证书
Redhat 系
#复制证书文件到 /etc/pki/ca-trust/source/anchors
#复制证书文件到 /usr/share/pki/ca-trust-source/anchors/
update-ca-trust
Windows
certutil -addstore -f root "foobar.cer"
★ 不同类型证书主要属性
[!CAUTION]
在命令中作为
-addext
参数时,,
前后不要有空格。
根 CA
-
basicConstraints=critical,CA:TRUE,pathlen:1
-
keyUsage=critical,digitalSignature,keyCertSign,cRLSign
-
subjectKeyIdentifier=hash
-
authorityKeyIdentifier=none
SSL (HTTPS)
- basicConstraints=critical,CA:FALSE
- authorityKeyIdentifier=keyid
- subjectKeyIdentifier=hash
- keyUsage=critical,digitalSignature
- extendedKeyUsage=serverAuth,clientAuth
- subjectAltName=DNS:*.example.com,DNS:example.com
VPN 客户端
- basicConstraints=critical,CA:FALSE
- authorityKeyIdentifier=keyid
- subjectKeyIdentifier=hash
- keyUsage=critical,digitalSignature,keyEncipherment
- extendedKeyUsage=clientAuth
- subjectAltName=DNS:example.com,email:[email protected]
VPN 服务端
- basicConstraints=critical,CA:FALSE
- authorityKeyIdentifier=keyid
- subjectKeyIdentifier=hash
- keyUsage=critical,digitalSignature,keyEncipherment
- extendedKeyUsage=serverAuth
- subjectAltName=DNS:DNS:example.com,email:[email protected]
软件
- basicConstraints=critical,CA:FALSE
- authorityKeyIdentifier=keyid
- subjectKeyIdentifier=hash
- keyUsage=critical,digitalSignature
- extendedKeyUsage=codeSigning