[!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