如何使用 Openssl 创建一个证书

如何使用 Openssl 创建一个证书

使用 openssl 创建证书的命令记录

关于格式

  • PEMOpenssl 使用 PEM(Privacy Enhanced Mail) 格式来存放各种信息, 它是 openssl 默认采用的信息存放方式。ApacheNGINX 服务器偏向于使用这种编码格式。Openssl 中的 PEM 文件一般包含如下信息:

    • 内容类型:表明本文件存放的是什么信息内容,它的形式为 ----- BEGIN XXXX -----,与结尾的 ----- END XXXX ----- 对应;
    • 头信息:表明数据是如果被处理后存放,openssl 中用的最多的是加密信息,比如加密算法以及初始化向量 iv
    • 信息体:为 Base64 编码的数据。可以包括所有私钥(RSADSA)、公钥(RSADSA)和 (x509) 证书。它存储用 Base64 编码的 DER 格式数据,用 ascii 报头包围,因此适合系统之间的文本模式传输。
  • DER - 编码规则 (DER) 可包含所有私钥、公钥和证书。JavaWindows 服务器偏向于使用这种编码格式。它是大多数浏览器的缺省格式,并按 ASN1 DER 格式存储。它是无报头的, 而 PEM 是用文本报头包围的 DER

  • 证书用途

    • digitalSignature: 电子签名
    • nonRepudiation: 不可否认
    • keyEncipherment: 密钥加密
    • dataEncipherment: 数据加密
    • keyAgreement:
    • keyCertSign: 密钥证书签名
    • cRLSign: cRl 签名
    • encipherOnly: 仅加密
    • decipherOnly: 仅解密

命令


cat > v3.ext << EOF
# 自签名根证书
[ v3_ca ]
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical,CA:true
keyUsage = cRLSign, keyCertSign
subjectKeyIdentifier = hash

# 证书
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# 用户证书
[ usr_cert ]
authorityKeyIdentifier = keyid,issuer
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
# 签名证书
# keyUsage = digitalSignature, nonRepudiation
# 加密证书
# keyUsage = keyEncipherment, dataEncipherment, keyAgreement
# 兼顾签名和加密
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement

EOF

# * - * # * - * # * - * # * - * # * - * # * - * # * - * # * - * # * - * # * - * #

# 1. 生成根证书私钥

openssl genpkey -algorithm RSA -quiet -outform PEM -pkeyopt rsa_keygen_bits:2048 \
        -out rsa_openssl_root_certificate_private_key.pem
openssl genpkey -algorithm EC -quiet -outform PEM -pkeyopt ec_paramgen_curve:sm2 \
        -out sm2_openssl_root_certificate_private_key.pem

# 2. 利用根证书私钥生成根证书公钥(可选)

openssl pkey -pubout -inform PEM -outform PEM \
        -in rsa_openssl_root_certificate_private_key.pem \
        -out rsa_openssl_root_certificate_public_key.pem
openssl pkey -pubout -inform PEM -outform PEM \
        -in sm2_openssl_root_certificate_private_key.pem \
        -out sm2_openssl_root_certificate_public_key.pem

# 3. 密钥格式转换

openssl pkey -inform PEM -outform DER \
        -in rsa_openssl_root_certificate_private_key.pem \
        -out rsa_openssl_root_certificate_private_key.der
openssl pkey -inform PEM -outform DER \
        -in sm2_openssl_root_certificate_private_key.pem \
        -out sm2_openssl_root_certificate_private_key.der

openssl pkey -inform DER -outform PEM \
        -in rsa_openssl_root_certificate_private_key.der \
        -out rsa_openssl_root_certificate_private_key.convert.pem
openssl pkey -inform DER -outform PEM \
        -in sm2_openssl_root_certificate_private_key.der \
        -out sm2_openssl_root_certificate_private_key.convert.pem

# 4. 根证书私钥转换成 Java 能处理的 PKCS#8 格式(可选)

openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \
        -in rsa_openssl_root_certificate_private_key.pem \
        -out rsa_openssl_root_certificate_private_key_pkcs8.pem
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \
        -in sm2_openssl_root_certificate_private_key.pem \
        -out sm2_openssl_root_certificate_private_key_pkcs8.pem

# 5. 生成根证书请求

openssl req -new -noenc -keyform PEM -outform PEM \
        -key rsa_openssl_root_certificate_private_key.pem \
        -out rsa_openssl_root_certificate_signing_request.pem \
        -subj "/C=CN/ST=Shanghai/L=Shanghai/O=Agree CO.,Ltd./OU=Open Bank Link/CN=This is a oblink root certificate/emailAddress=bmsd@agree.com.cn"
openssl req -new -noenc -keyform PEM -outform PEM \
        -key sm2_openssl_root_certificate_private_key.pem \
        -out sm2_openssl_root_certificate_signing_request.pem \
        -subj "/C=CN/ST=Shanghai/L=Shanghai/O=Agree CO.,Ltd./OU=Open Bank Link/CN=This is a oblink root certificate/emailAddress=bmsd@agree.com.cn" \
        -sigopt "distid:1234567812345678"

# 6. 根证书请求验证

openssl req -check -sha256 -inform PEM -in rsa_openssl_root_certificate_signing_request.pem
openssl req -check -sm3 -inform PEM -in sm2_openssl_root_certificate_signing_request.pem

# 7. 证书请求格式转换

openssl req -inform PEM -outform DER \
        -in rsa_openssl_root_certificate_signing_request.pem \
        -out rsa_openssl_root_certificate_signing_request.der
openssl req -inform PEM -outform DER \
        -in sm2_openssl_root_certificate_signing_request.pem \
        -out sm2_openssl_root_certificate_signing_request.der

# 8. 生成根证书

openssl x509 -req -days 365 -sha256 -extfile v3.ext -extensions v3_req \
        -keyform PEM -outform PEM -key rsa_openssl_root_certificate_private_key.pem \
        -in rsa_openssl_root_certificate_signing_request.pem \
        -out rsa_openssl_root_certificate.pem
openssl x509 -req -days 365 -sm3    -extfile v3.ext -extensions v3_req \
        -keyform PEM -outform PEM -key sm2_openssl_root_certificate_private_key.pem \
        -in sm2_openssl_root_certificate_signing_request.pem \
        -out sm2_openssl_root_certificate.pem \
        -sigopt "distid:1234567812345678" -vfyopt "distid:1234567812345678"

# 9. 从根证书获取证书请求

openssl x509 -x509toreq -keyform PEM -inform PEM -outform PEM \
        -key rsa_openssl_root_certificate_private_key.pem \
        -in rsa_openssl_root_certificate.pem \
        -out rsa_openssl_root_certificate_signing_request_form_certificate.pem
openssl x509 -x509toreq -keyform PEM -inform PEM -outform PEM \
        -key sm2_openssl_root_certificate_private_key.pem \
        -in sm2_openssl_root_certificate.pem \
        -out sm2_openssl_root_certificate_signing_request_form_certificate.pem

# 10. 根证书格式转换

openssl x509 -inform PEM -outform DER \
        -in rsa_openssl_root_certificate.pem -out rsa_openssl_root_certificate.der
openssl x509 -inform PEM -outform DER \
        -in sm2_openssl_root_certificate.pem -out sm2_openssl_root_certificate.der

# 11. 从根证书中获取根证书公钥(可选)

openssl x509 -pubkey -nocert -inform PEM -outform PEM \
        -in rsa_openssl_root_certificate.pem \
        -out rsa_openssl_root_certificate_public_key_from_certificate.pem
openssl x509 -pubkey -nocert -inform PEM -outform PEM \
        -in sm2_openssl_root_certificate.pem \
        -out sm2_openssl_root_certificate_public_key_form_certificate.pem

# * - * # * - * # * - * # * - * # * - * # * - * # * - * # * - * # * - * # * - * #

# 1. 生成证书私钥

openssl genpkey -algorithm RSA -quiet -outform PEM -pkeyopt rsa_keygen_bits:2048 \
        -out rsa_openssl_certificate_private_key.pem
openssl genpkey -algorithm EC -quiet -outform PEM -pkeyopt ec_paramgen_curve:sm2 \
        -out sm2_openssl_certificate_private_key.pem

# 2. 利用证书私钥生成证书公钥(可选)

openssl pkey -pubout -inform PEM -outform PEM \
        -in rsa_openssl_certificate_private_key.pem \
        -out rsa_openssl_certificate_public_key.pem
openssl pkey -pubout -inform PEM -outform PEM \
        -in sm2_openssl_certificate_private_key.pem \
        -out sm2_openssl_certificate_public_key.pem

# 3. 证书私钥转换成 Java 能处理的 PKCS#8 格式(可选)

openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \
        -in rsa_openssl_certificate_private_key.pem \
        -out rsa_openssl_certificate_private_key_pkcs8.pem
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \
        -in sm2_openssl_certificate_private_key.pem \
        -out sm2_openssl_certificate_private_key_pkcs8.pem

# 4. 生成证书请求

openssl req -new -noenc -keyform PEM -outform PEM \
        -key rsa_openssl_certificate_private_key.pem \
        -out rsa_openssl_certificate_signing_request.pem \
        -subj "/C=CN/ST=Shannxi/L=Xi'an/O=Agree CO.,Ltd./OU=Open Bank Link develop/CN=This is a oblink certificate/emailAddress=oblink@agree.com.cn"
openssl req -new -noenc -keyform PEM -outform PEM \
        -key sm2_openssl_certificate_private_key.pem \
        -out sm2_openssl_certificate_signing_request.pem \
        -subj "/C=CN/ST=Shannxi/L=Xi'an/O=Agree CO.,Ltd./OU=Open Bank Link develop/CN=This is a oblink certificate/emailAddress=oblink@agree.com.cn" \
        -sigopt "distid:1234567812345678"

# 5. 根证书签署证书

openssl x509 -req -days 365 -sha256 -CAcreateserial -extfile v3.ext \
        -extensions v3_req -CAform PEM -CAkeyform PEM -inform PEM -outform PEM \
        -CA rsa_openssl_root_certificate.pem \
        -CAkey rsa_openssl_root_certificate_private_key.pem \
        -in rsa_openssl_certificate_signing_request.pem \
        -out rsa_openssl_certificate.pem
openssl x509 -req -days 365 -sm3 -CAcreateserial -extfile v3.ext \
        -extensions v3_req -CAform PEM -CAkeyform PEM -inform PEM -outform PEM \
        -CA sm2_openssl_root_certificate.pem \
        -CAkey sm2_openssl_root_certificate_private_key.pem \
        -in sm2_openssl_certificate_signing_request.pem \
        -out sm2_openssl_certificate.pem \
        -sigopt "distid:1234567812345678" -vfyopt "distid:1234567812345678"

# 6. 从证书中获取证书公钥(此处获取的公钥是根证书的, 可选)

openssl x509 -pubkey -nocert -inform PEM -outform PEM \
        -in rsa_openssl_certificate.pem \
        -out rsa_openssl_issuer_certificate_public_key_from_certificate.pem
openssl x509 -pubkey -nocert -inform PEM -outform PEM \
        -in rsa_openssl_certificate.pem \
        -out rsa_openssl_issuer_certificate_public_key_from_certificate.pem


# * - * # * - * # * - * # * - * # * - * # * - * # * - * # * - * # * - * # * - * #


# 1. 私钥加密码

openssl pkey -aes256 -passout pass:ImAPassword -inform PEM -outform PEM \
        -in rsa_openssl_certificate_private_key.pem \
        -out rsa_openssl_certificate_private_key_encipher.pem
openssl pkey -aes256 -passout pass:ImAPassword -inform PEM -outform PEM \
        -in sm2_openssl_certificate_private_key.pem \
        -out sm2_openssl_certificate_private_key_encipher.pem

# 2. 私钥去解密

openssl pkey -passin pass:ImAPassword -inform PEM -outform PEM \
        -in rsa_openssl_certificate_private_key_encipher.pem \
        -out rsa_openssl_certificate_private_key_decipher.pem
openssl pkey -passin pass:ImAPassword -inform PEM -outform PEM \
        -in sm2_openssl_certificate_private_key_encipher.pem \
        -out sm2_openssl_certificate_private_key_decipher.pem

# 3. 私钥改解密

openssl pkey -passin pass:ImAPassword -aes256 -passout pass:ImAPasswordToo \
        -inform PEM -outform PEM \
        -in rsa_openssl_certificate_private_key_encipher.pem \
        -out rsa_openssl_certificate_private_key_encipher2.pem
openssl pkey -passin pass:ImAPassword -aes256 -passout pass:ImAPasswordToo \
        -inform PEM -outform PEM \
        -in sm2_openssl_certificate_private_key_encipher.pem \
        -out sm2_openssl_certificate_private_key_encipher2.pem

# 4. 证书导出 PKCS#12

openssl pkcs12 -export -passout pass:ImApassword \
        -inkey rsa_openssl_root_certificate_private_key.pem \
        -in rsa_openssl_root_certificate.pem \
        -out rsa_openssl_root_certificate.pfx
openssl pkcs12 -export -passout pass:ImApassword \
        -inkey rsa_openssl_certificate_private_key.pem \
        -in rsa_openssl_certificate.pem \
        -CAfile rsa_openssl_root_certificate.pem \
        -out rsa_openssl_certificate.pfx

# 5. 证书查看(-noenc 代表私钥未加密)

openssl pkcs12 -info -noenc -passin pass:ImApassword -in rsa_openssl_root_certificate.pfx
openssl pkcs12 -info -noenc -passin pass:ImApassword -in rsa_openssl_certificate.pfx

# 6. 加验签

openssl pkeyutl -sign -rawin -keyform PEM \
        -inkey rsa_openssl_certificate_private_key.pem -in v3.ext  \
        -out rsa_sign -digest sha256
openssl pkeyutl -verify -rawin -certin \
        -keyform PEM -inkey rsa_openssl_certificate.pem -in v3.ext \
        -sigfile rsa_sign -digest sha256
openssl pkeyutl -sign -rawin -keyform PEM \
        -inkey sm2_openssl_certificate_private_key.pem -in v3.ext \
        -out sm2_sign     -digest sm3 -pkeyopt distid:"1234567812345678"
openssl pkeyutl -verify -rawin -certin -keyform PEM \
        -inkey sm2_openssl_certificate.pem-in v3.ext \
        -sigfile sm2_sign -digest sm3 -pkeyopt distid:"1234567812345678"