OpenSSL - 使用 openssl 生成 TLS 憑證
如何使用 openssl 生成 TLS 需要的憑證
生成自簽伺服器證書¶
openssl req -x509 -nodes -newkey rsa:2048 \
-subj='/CN=Self Sign Cert' \
-extensions usr_cert \
-addext "keyUsage = nonRepudiation, digitalSignature, keyEncipherment" \
-addext "extendedKeyUsage = serverAuth" \
-addext "subjectAltName = DNS:www.server.com,DNS:localhost,IP:127.0.0.1" \
-out=crt.pem -keyout=key.pem
生成完整憑證鏈¶
生成自簽根憑證 Generate self sign root CA cert¶
# 生成私鑰
# generate private key
openssl genrsa -out=root_ca_key.pem 2048
# 用私鑰生成根憑證
# generate root cert from private key
openssl req -x509 -sha256 -new -days=10950 \
-subj='/CN=Root CA/C=HK/L=Hong Kong' \
-addext "keyUsage = critical, keyCertSign, cRLSign" \
-key=root_ca_key.pem -out=root_ca_crt.pem
# 生成流水號,每次簽發證書,流水號會加一
# create root ca serial number file, this will record how many cert this ca issued
openssl rand -hex -out=root_ca_srl.txt 20
# 檢查憑證訊息
# check cert info
openssl x509 -in root_ca_crt.pem -text
生成中間憑證 Issue intermediate CA cert¶
# 憑證配置
# cert config, ref: https://www.openssl.org/docs/man1.0.2/man5/x509v3_config.html
tee inter_ca_ext.cnf <<EOF
[inter_ca_ext]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:TRUE, pathlen:0
keyUsage = critical, keyCertSign, cRLSign
EOF
# 生成私鑰
# generate private key
openssl genrsa -out=inter_ca_key.pem 2048
# 生成 CSR
# generate CSR (Certificate Signing Request)
openssl req -sha256 -new -subj='/CN=Intermediate CA/C=HK/L=Hong Kong' \
-key=inter_ca_key.pem -out=inter_ca_csr.pem
# 簽發中間憑證
# issue intermediate ca with root ca
openssl x509 -req -days=1095 -CAserial=root_ca_srl.txt \
-CA=root_ca_crt.pem -CAkey=root_ca_key.pem \
-extfile=inter_ca_ext.cnf -extensions=inter_ca_ext \
-in=inter_ca_csr.pem -out=inter_ca_crt.pem
# 生成流水號,每次簽發證書,流水號會加一
# create root ca serial number file, this will record how many cert this ca issued
openssl rand -hex -out=inter_ca_srl.txt 20
# 檢查憑證訊息
# check cert info
openssl x509 -in inter_ca_crt.pem -text
生成伺服器憑證 Generate Server Cert¶
# 憑證配置
# cert config
tee server_ext.cnf <<EOF
[server_ext]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
basicConstraints = critical, CA:FALSE
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = critical, serverAuth
subjectAltName = @server_ext_san
[server_ext_san]
DNS.1 = nginx.test.isaac.com
DNS.2 = localhost
IP.1 = 127.0.0.1
EOF
# 生成私鑰
# generate private key
openssl genrsa -out=server_key.pem 2048
# 生成 CSR
openssl req -sha256 -new -subj "/CN=Server Cert/C=HK/L=Hong Kong" \
-key=server_key.pem -out=server_csr.pem
# 簽發伺服器憑證
# issue server cert with intermediate ca
openssl x509 -req -days=365 -CAserial=inter_ca_srl.txt \
-CA=inter_ca_crt.pem \-CAkey=inter_ca_key.pem \
-extfile=server_ext.cnf -extensions=server_ext \
-in=server_csr.pem -out=server_crt.pem
# 檢查憑證訊息
# check cert info
openssl x509 -in server_crt.pem -text
生成客戶端憑證 Generate Client Cert¶
# 憑證配置
# cert config
tee client_ext.cnf <<EOF
[client_ext]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
basicConstraints = critical, CA:FALSE
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = critical, clientAuth
EOF
# 生成私鑰
# generate private key
openssl genrsa -out=client_key.pem 2048
# 生成 CSR
openssl req -sha256 -new -subj "/CN=Client Cert/C=HK/L=Hong Kong" \
-key=client_key.pem -out=client_csr.pem
# 簽發客戶端憑證
# issue client cert with intermediate ca
openssl x509 -req -days=365 -CAserial=inter_ca_srl.txt \
-CA=inter_ca_crt.pem \-CAkey=inter_ca_key.pem \
-extfile=client_ext.cnf -extensions=client_ext \
-in=client_csr.pem -out=client_crt.pem
# 檢查憑證訊息
# check cert info
openssl x509 -in client_crt.pem -text
其他實用命令¶
下載伺服器憑證¶
下載憑證鏈¶
openssl s_client -showcerts -verify 5 -connect www.google.com:443 < /dev/null | awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="cert_chain.pem"; print >out}'
增加信任憑證¶
ubuntu
sudo apt-get install -y ca-certificates
sudo cp ca.crt /usr/local/share/ca-certificates
sudo update-ca-certificates
powershell
Import-Certificate -FilePath "C:\crt.pem" -CertStoreLocation cert:\CurrentUser\Root
Import-Certificate -FilePath "C:\crt.pem" -CertStoreLocation Cert:\LocalMachine\Root
docker ubuntu container
docker run --rm -it \
-v=/my_certs/root_crt.pem:/etc/ssl/certs/root_crt.pem \
wbitt/network-multitool bash
加密/解密私鑰¶
# 生成 RSA 私鑰
openssl genrsa -out=rsa_key.pem 2048
# 將私鑰轉換 pkcs8 格式
openssl pkcs8 -topk8 -in rsa_key.pem -out key.pem -nocrypt
# 加密私鑰
openssl pkcs8 -topk8 -in key.pem -out key_encrypt.pem
# 解密私鑰
openssl pkcs8 -topk8 -in key_encrypt.pem -out key_decrypt.pem
格式轉換¶
## 生成自簽證書
openssl req -x509 -nodes -newkey rsa:2048 -subj='/CN=Self Sign Cert' -out=crt.pem -keyout=key.pem
## PEM 轉 PFX
openssl pkcs12 -in=crt.pem -inkey=key.pem -export -out=crt.pfx
## PFX 轉 PEM
openssl pkcs12 -in=crt.pfx -out=crt_key.pem -nodes
## PEM 轉 DER
openssl x509 -outform der -in crt.pem -out crt.der
## DER 轉 PEM
openssl x509 -inform der -in crt.der -out crt_from_der.pem
## PKCS#8 轉 PKCS#1
openssl rsa -in key.pem -out key_pkcs1.pem