OpenSSL生成CA(根证书)并自签署证书(支持IP地址)

Eave 2024.10.30

X.509证书包含三个文件:key,csr,crt

key是服务器上的私钥文件,用于对发送给客户端数据的加密,以及对从客户端接收到数据的解密

csr是证书签名请求文件,用于提交给证书颁发机构(CA)对证书签名

crt是由证书颁发机构(CA)签名后的证书,或者是开发者自签名的证书,包含证书持有人的信息,持有的公钥,以及签署者的签名等信息

备注:在密码学中,X.509是一个标准,规范了公开秘钥认证、证书吊销列表、授权凭证、凭证路径验证算法等。

一、生成CA根证书

生成CA根证书私钥

openssl genrsa -des3 -out root.pass.key 2048

去除CA私钥中的密码

openssl rsa -in root.pass.key -out root.key

生成CA根证书包括了国家(C=CN)、省/州(ST=BJ)、城市(L=BJ)、组织/公司(O=MyRootCA)、组织单位/部门(OU=MyCA)、通用名称(CN=CA)等信息

openssl req -new -sha256 -x509 -days 3650 -key root.key -subj "/C=CN/ST=Chonqing/L=Chonqing/O=CA/OU=CA/CN=CA" -out root.crt

二、生成服务器证书

生成v3.ext文件

cat > $HOST.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
subjectAltName=@alt_names
[alt_names]
DNS.1=${HOST}
DNS.2=*.${HOST}
IP.1=127.0.0.1
EOF

keyUsage各项值的含义:

数字签名(Digital Signature):用于对数据进行签名,确保数据的完整性和来源的真实性

密钥加密(Key Encipherment):用于加密和解密数据

内容承诺(Content Commitment):确保数据在传输过程中的完整性和未被篡改

非否认(Non-Repudiation):确保发送方不能否认其发送的数据

生成服务器证书

openssl req -newkey rsa:2048 -nodes -keyout $HOST.key -subj "/C=CN/ST=Chonqing/L=Chonqing/O=MyRootServer/OU=MyServer/CN=$HOST" -out $HOST.csr

对服务器证书进行签名

openssl x509 -req -sha256 -days 3650 -CA root.crt -CAkey root.key -CAcreateserial -extfile $HOST.ext -in $HOST.csr -out $HOST.crt

查看服务器证书信息

openssl x509 -text -noout -in $HOST.crt

三、信任CA证书

CentOS

cp root.crt /etc/pki/ca-trust/source/anchors/
update-ca-trust

Ubuntu

cp root.crt /usr/local/share/ca-certificates/
update-ca-certificates

Windows

右键文件,选择安装证书,选择本地计算机,指定安装到受信任的根证书颁发机构,即可


附:证书生成脚本

#!/bin/bash

HOST=$1

# 获取10年后的今天
# startDate=`date +"%Y-%m-%d"`
# endDate=`date -d "$startDate 10 years" +"%Y-%m-%d"`

# 使用date命令计算天数差
# days=$(( ($(date -d "$endDate" +%s) - $(date -d "$startDate" +%s)) / 86400 ))
days=$(( ($(date -d "10 years" +%s) - $(date +%s)) / 86400 ))


# 判断是否有根证书,有就不生成根证书了
if [ ! -e "root.crt" ]; then

    # 生成CA根证书私钥
    openssl genrsa -des3 -out root.pass.key 2048

    # 去除CA根证书私钥中的密码
    openssl rsa -in root.pass.key -out root.key

    # 生成CA根证书 包括了国家(C=CN)、省/州(ST=BJ)、城市(L=BJ)、组织/公司(O=MyRootCA)、组织单位/部门(OU=MyCA)、通用名称(CN=CA)等信息
    openssl req -new -sha256 -x509 -days $days -key root.key -subj "/C=CN/ST=Chonqing/L=Chonqing/O=CA/OU=CA/CN=CA" -out root.crt
fi


# 生成v3.ext文件
cat > $HOST.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
subjectAltName=@alt_names
[alt_names]
DNS.1=${HOST}
DNS.2=*.${HOST}
EOF

# 生成服务器证书
openssl req -newkey rsa:2048 -nodes -keyout $HOST.key -subj "/C=CN/ST=Chonqing/L=Chonqing/O=MyRootServer/OU=MyServer/CN=$HOST" -out $HOST.csr

# 对服务器证书进行签名
openssl x509 -req -sha256 -days $days -CA root.crt -CAkey root.key -CAcreateserial -extfile $HOST.ext -in $HOST.csr -out $HOST.crt

# 将CRT证书转为P12证书(可对PDF文件进行签名)
openssl pkcs12 -export -clcerts -in $HOST.crt -inkey $HOST.key -out $HOST.p12

# 将P12证书转为CRT证书
# openssl pkcs12 -in $HOST.p12 -nokeys -out $HOST.crt # 导出证书
# openssl pkcs12 -in $HOST.p12 -nocerts -nodes -out $HOST.key # 导出私钥