【安全贴士】一键生成证书脚本

这里演示如何通过命令行一键生成自签名CA证书,以及对于已有的证书生成服务证书库和信任证书库。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
#!/usr/bin/env bash
####################################################
# 一键生成证书库server.p12和信任证书库root.p12
# 证书库由openssl命令生成,信任证书库由keytool工具生成。
# ./x509.sh
####################################################

# 定义变量
export CA_WORK_DIR=`pwd`
export config="${CA_WORK_DIR}/myopenssl.cnf"
export root_key_password=123456
export root_p12_password=123456
export middle_key_password=123456
export server_key_password=123456
export server_p12_password=123456
export sign_key_password=123456
export cn="test20201229"
export days=3550

# 生成必要的文件
[[ -d private ]] || mkdir private
[[ -d csr ]] || mkdir csr
[[ -d certs ]] || mkdir certs 
# 初始化索引文件
[[ -f index.txt ]] || touch index.txt
# 吊销序列号文件
[[ -f index.txt ]] || touch crlnumber

# 初始化openssl配置
grep "v3_server_client" $config &>/dev/null
if [[ "$?" != "0" ]]; then
    cp /etc/pki/tls/openssl.cnf $config
    cat <<EOF >>$config

[ v3_rootca ]
basicConstraints = critical, CA:true
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
keyUsage = critical, cRLSign, digitalSignature, keyCertSign
crlDistributionPoints=URI:https://example.com/rootca.crl

[ v3_middleca ]
basicConstraints = critical, CA:true
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
keyUsage = critical, cRLSign, digitalSignature, keyCertSign
crlDistributionPoints=URI:https://example.com/middleca.crl

[ v3_server_client ]
basicConstraints        = critical, CA:FALSE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always, issuer:always
keyUsage                = critical, nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
extendedKeyUsage        = critical, serverAuth, clientAuth
crlDistributionPoints   = URI:https://example.com/server.crl

[ v3_sign ]
basicConstraints        = critical, CA:FALSE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always, issuer:always
keyUsage                = critical, digitalSignature
extendedKeyUsage        = critical, codeSigning
EOF
fi

# 生成CA根证书
if [[ ! -f private/root.key ]]; then
    (umask 077; openssl genrsa -aes256 -passout pass:${root_key_password} -out private/root.key 3072)
    openssl req -x509 -days 3650 -sha256 -extensions v3_rootca -key private/root.key -passin pass:${root_key_password} \
        -out root.crt -subj "/C=CN/ST=SX/L=XA/O=xncoding/OU=GTS/CN=root.xncoding.com/emailAddress=root@xncoding.com" \
        -config ${config}
    keytool -import -noprompt -trustcacerts -alias rootca -file root.crt -keystore root.p12 \
        -storetype PKCS12 -storepass ${root_p12_password}
fi

# 生成二级CA证书
if [[ ! -f private/middle.key ]]; then
    (umask 077; openssl genrsa -aes256 -passout pass:${middle_key_password} -out private/middle.key 3072)
    openssl req -new -extensions v3_middleca -key private/middle.key -passin pass:${middle_key_password} \
        -out csr/middle.csr -subj "/C=CN/ST=SX/L=XA/O=xncoding/OU=DC/CN=middle/emailAddress=middle@xncoding.com" \
        -config ${config}
    openssl x509 -req -extensions v3_middleca -days ${days} -sha256 -CAcreateserial -CA root.crt \
        -CAkey private/root.key -passin pass:${root_key_password} -in csr/middle.csr -out middle.crt \
        -extfile ${config}
fi

# 签发服务证书
(umask 077; openssl genrsa -aes256 -passout pass:${server_key_password} -out private/server.key 3072)
openssl req -new -extensions v3_server_client -key private/server.key -passin pass:${server_key_password} \
    -out csr/server.csr -subj "/C=CN/ST=SX/L=XA/O=xncoding/OU=DC/CN=${cn}/emailAddress=${cn}@xncoding.com" \
    -config ${config}
openssl x509 -req -extensions v3_server_client -days ${days} -sha256 -CAcreateserial -CA middle.crt \
    -CAkey private/middle.key -passin pass:${middle_key_password} -in csr/server.csr -out certs/server.crt \
    -extfile ${config}

# 导出服务证书为PKCS12的证书链
[[ -f cachain.crt ]] || cat middle.crt root.crt > cachain.crt
openssl pkcs12 -export -inkey private/server.key -passin pass:${server_key_password} \
    -in certs/server.crt -chain -CAfile cachain.crt -out certs/server.p12 -password pass:${server_p12_password} \
    -keypbe aes-256-cbc -certpbe aes-256-cbc

# 最后删除临时文件
rm -f csr/server.csr csr/middle.csr

# 查看证书库信息
# openssl pkcs12 -info -in certs/server.p12 -nodes -passin pass:${server_p12_password}