OpenSSL证书

110 阅读5分钟

术语

  • PKI 公钥基础设施(Public Key Infrastructure)
  • CSR 证书签署请求(certificate signing request)
  • CA 证书颁发机构(certificate authority)
  • DN 区分名称(Distinguised Name)
  • CN 通用名称(Common Name)
  • FQDN 完全合格域名(Fully Qualified Domain Name)
  • 自签证书(self-signed certificate)
  • CA证书
  • 证书
  • 私钥

私钥

# 生成加密的私钥
openssl genrsa -des3 -out domain.key 2048
# 查看加密私钥。输入密码
openssl rsa -check -in domain.key

# 加密私钥
openssl rsa -des3 -in domain.key -out encrypt.key
# 解密私钥
openssl rsa -in encrypt.key -out decrypt.key

CSR

# 一个 CSR 主要是由一个密钥对的公钥和一些附加信息组成
# CSR 可以用来向证书颁发机构请求 SSL 证书
### 交互式CSR
# Country Name (2 letter code) [AU]:US
# State or Province Name (full name) [Some-State]:New York
# Locality Name (eg, city) []:Brooklyn
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Brooklyn Company
# Organizational Unit Name (eg, section) []:Technology Division
# Common Name (e.g. server FQDN or YOUR name) []:examplebrooklyn.com
# Email Address []:
### 非交互式
# -subj "/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/CN=examplebrooklyn.com"

# 生成私钥和csr
openssl req -newkey rsa:2048 -nodes -keyout domain.key -out domain.csr
# openssl req -newkey rsa:2048 -nodes -keyout domain.key -out domain.csr -subj "/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/CN=examplebrooklyn.com"
# 用rsa算法生产2048位密钥,--nodes不密码加密
# domain.key 私钥
# domain.csr 证书签署请求

#用私钥生成csr
openssl req -key domain.key -new -out domain.csr

# 用证书和私钥生成csr
openssl x509 -in domain.crt -signkey domain.key -x509toreq -out domain.csr
# domain.crt 证书
# domain.key 私钥
# domain.csr 证书签署请求
# -x509toreq 指定一个 X509 证书来制作 CSR

生成SSL证书

# 一个有效的和免费的解决方案是签署证书,自签证书(self-signed certificate)
# 自签证书和 CA 签名证书一样可以用来加密数据,但是你的用户会显示一个警告,说这个证书不被他们的计算机或浏览器信任

# 生成私钥和证书
openssl req -newkey rsa:2048 -nodes -keyout domain.key -x509 -days 365 -out domain.crt
# domain.key 私钥
# domain.crt 证书

# 用私钥生成证书
openssl req -key domain.key -new -x509 -days 365 -out domain.crt
# -new 启动CSR信息提问

# 用私钥和csr生成证书
openssl x509 -signkey domain.key -in domain.csr -req -days 365 -out domain.crt

查看证书

# 查看csr
openssl req -text -noout -verify -in domain.csr

# 查看证书crt
openssl x509 -text -noout -in domain.crt

# 验证证书由CA签署
openssl verify -verbose -CAfile ca.crt domain.crt

# 验证私钥是否与证书和csr匹配
# 输出相同,私钥、证书、csr有可能相关
openssl rsa -noout -modulus -in domain.key | openssl md5
openssl x509 -noout -modulus -in domain.crt | openssl md5
openssl req -noout -modulus -in domain.csr | openssl md5

# 验证证书期限
openssl x509 -noout -dates -in domain.crt
# notBefore=May  7 03:12:27 2024 GMT
# notAfter=May  7 03:12:27 2025 GMT

证书格式转换

# 证书和 CSR 文件是以 PEM 格式编码的,所有证书都是 ASCII 码 PEM 编码的 X.509 证书
# 证书格式:pem、der、p7b、pfx

# 将PEM编码证书crt转换成DER编码证书der(二进制)
# 场景:DER 格式通常与 Java一起使用
openssl x509 -in domain.crt -outform der -out domain.der

# 将DER转换成PEM格式
openssl x509 -inform der -in domain.der -out domain.crt

# 将PEM转换成PKCS7,也称P7B
# PKCS7 文件,也被称为 P7B,通常用于 Java Keystores 和 Microsoft IIS(Windows)
# P7B是 ASCII 文件,可以包含证书和 CA 证书
openssl crl2pkcs7 -nocrl -certfile domain.crt -certfile ca-chain.crt -out domain.p7b

# 将PKCS7转换成PEM
openssl pkcs7 -in domain.p7b -print_certs -out domain.crt

# 将PEM转换为PKCS12,也称pfx
# 用私钥(domain.key)和证书(domain.crt)组合成PKCS12文件,提示输入密码
# PKCS12 文件,也被称为 PFX 文件,通常用于在 Micrsoft IIS(Windows)中导入和导出证书链
openssl pkcs12 -inkey domain.key -in domain.crt -export -out domain.pfx

# 将PKCS12转换为PEM
openssl pkcs12 -in domain.pfx -nodes -out domain.combined.crt

自签证书

### 带CA证书和不带CA证书
- 带CA的自签名证书:在这种情况下,用户不仅生成自己的证书,还创建了自己的CA,然后使用该CA签名其证书。这意味着用户有自己的证书颁发机构环境,可以用于签名多个证书。
- 不带CA的自签名证书:在这种情况下,用户只是为自己创建和签名一个证书,而没有创建CA。这个证书是单独存在的,不依赖于任何CA结构。

# 生成CA证书
mkdir -p ca/{certs,keys}
# 生成CA私钥
openssl ecparam -genkey -name secp384r1 -out ca/keys/ca.key
# 生成CA的CSR
openssl req -new -subj "/C=CN/ST=Anhui/L=Hefei/O=xxoo/OU=ca/CN=ca.xxoo.com" -key ca/keys/ca.key -out ca/certs/ca.csr
# 生成CA证书扩展信息
echo "subjectKeyIdentifier=hash" > ca/certs/ca_cert_extensions
echo "authorityKeyIdentifier=keyid:always,issuer" >> ca/certs/ca_cert_extensions
echo "basicConstraints=critical,CA:true" >> ca/certs/ca_cert_extensions
echo "subjectAltName=DNS.1:localhost,DNS.2:ca.xxoo.com,IP:127.0.0.1" >> ca/certs/ca_cert_extensions
# 生成CA根证书
openssl x509 -req -days 3650 -sha256 -extfile ca/certs/ca_cert_extensions -signkey ca/keys/ca.key -in ca/certs/ca.csr  -out ca/certs/ca.crt


# 生成服务证书
mkdir -p server/{certs,keys}
# 生成服务私钥
openssl ecparam -genkey -name secp384r1 -out server/keys/server.key
# 生成CSR
openssl req -new \
    -subj "/C=CN/ST=Anhui/L=Hefei/O=xxoo/OU=server/CN=server.xxoo.com" \
    -key server/keys/server.key -out server/certs/server.csr
# 生成服务扩展信息(可省略)
echo "subjectKeyIdentifier = hash" > server/certs/server_cert_extensions
echo "authorityKeyIdentifier = keyid:always,issuer" >> server/certs/server_cert_extensions
echo "basicConstraints = CA:FALSE" >> server/certs/server_cert_extensions
echo "keyUsage = nonRepudiation, digitalSignature, keyEncipherment" >> server/certs/server_cert_extensions
echo "subjectAltName = DNS.1:localhost,DNS.2:server.xxoo.com,IP:127.0.0.1" >> server/certs/server_cert_extensions
# 生成随机序列号
openssl x509 -req -in server/certs/server.csr -out server/certs/server.crt -CA ca/certs/ca.crt -CAkey ca/keys/ca.key -CAcreateserial
# 生成服务器证书
openssl x509 -req -days 3650 -sha256 \
  -extfile server/certs/server_cert_extensions \
  -CA ca/certs/ca.crt -CAkey ca/keys/ca.key \
  -in server/certs/server.csr -out server/certs/server.crt

# 浏览器验证
# 假定一个https服务已经使用了server/keys/server.key私钥文件与server/certs/server.crt证书文件,并启动了https服务(端口443),那么可以通过浏览器(如chrome)访问,查看其证书。
# 此时浏览器(如chrome)认为证书是不安全的,会有警告,我们可以在浏览器(如chrome)的设置中找到证书管理,在授权机构中导入前面生成的CA根证书ca/certs/ca.crt。
# 然后再重新访问https服务,就会发现证书已经是安全的了。

参考