Skip to content

Instantly share code, notes, and snippets.

@enihsyou
Created June 7, 2019 20:36
Show Gist options
  • Save enihsyou/b67a69cf41696326a6159d66a68140b5 to your computer and use it in GitHub Desktop.
Save enihsyou/b67a69cf41696326a6159d66a68140b5 to your computer and use it in GitHub Desktop.
一键创建SSL证书
#!/bin/bash
# CA文件夹目录
CA_HOME=${CA_HOME:?}
# CA配置文件
CA_CFG=${CA_CFG:?}
# CA证书路径
CA_CERT=${CA_CERT:?}
IDENTITY=${IDENTITY:?}
OUTDIR=${OUTDIR:?}
PRIK_FILE=${PRIK_FILE:?}
PRIK_PASS=${PRIK_PASS:?}
CSR_FILE=${CSR_FILE:?}
CERT_FILE=${CERT_FILE:?}
EXT_FILE=${EXT_FILE:?}
SIGN_EXT=${SIGN_EXT:?}
PKCS12_FILE=${PKCS12_FILE:?}
echo 创建输出目录
mkdir -p "$OUTDIR"
gen_key()
{
echo 创建私钥
openssl genpkey -algorithm RSA \
-pkeyopt rsa_keygen_bits:2048 \
-aes256 -pass "$PRIK_PASS" \
-out "$PRIK_FILE" || exit 1
}
show_key()
{
echo 查看公钥
openssl pkey -noout -text_pub -in "$PRIK_FILE" -passin "$PRIK_PASS" || exit 1
}
gen_csr()
{
echo 创建证书签署请求
openssl req -new -config "$EXT_FILE" \
-key "$PRIK_FILE" -passin "$PRIK_PASS" \
-out "$CSR_FILE" || exit 1
}
show_csr()
{
echo 查看CSR
openssl req -noout -text -in "$CSR_FILE" || exit 1
}
sign_csr()
{
echo 签署证书
touch "$CA_HOME"/index.txt
[[ ! -s "$CA_HOME"/serial ]] && echo 01 > "$CA_HOME"/serial
openssl ca -config "$CA_CFG" -passin "$PRIK_PASS" \
-extensions "$SIGN_EXT" \
-in "$CSR_FILE" \
-out "$CERT_FILE" || exit 1
cat "$CA_CERT" >> "$CERT_FILE"
}
gen_pkcs12()
{
echo 导出PKCS12
openssl pkcs12 -export \
-macalg sha256 -name "PKCS12 file for $IDENTITY" \
-inkey "$PRIK_FILE" \
-in "$CERT_FILE" -passin "$PRIK_PASS" \
-out "$PKCS12_FILE" -passout "$PRIK_PASS"
# https://www.openssl.org/docs/man1.1.0/man1/openssl.html#Pass-Phrase-Options
# PRIK_PASS文件的第一行是输入密码,第二行是输出密码
}
###
# 主入口
###
[ -s "$PRIK_FILE" ] || gen_key
show_key
[ -s "$CSR_FILE" ] || gen_csr
show_csr
[ -s "$CERT_FILE" ] || sign_csr
gen_pkcs12
###
# 创建新的证书
###
# CA文件夹目录
CA_HOME="$HOME"/.ssh/ca
# 私钥密码文件(简单起见使用相同的密码)
PASS_FILE="$HOME"/.ssh/ca/.keypass
# 当前CA文件夹目录(该变量方便脚本重用)
CA_HOME="$CA_HOME"/intermediate
# CA配置文件
CA_CFG="$CA_HOME"/openssl.cnf
# CA证书路径
CA_CERT="$CA_HOME"/certs/intermediate.pem.crt
IDENTITY=${IDENTITY:-localhost}
OUTDIR=generate/"$IDENTITY"
PRIK_FILE=${PRIK_FILE:-"$OUTDIR"/"$IDENTITY".key.rsa}
PRIK_PASS=${PRIK_PASS:-file:"$PASS_FILE"}
CSR_FILE=${CSR_FILE:-"$OUTDIR"/"$IDENTITY".pem.csr}
CERT_FILE="$OUTDIR"/"$IDENTITY".pem.crt
PKCS12_FILE="$OUTDIR"/"$IDENTITY".p12
EXT_FILE=csr_ext.cnf
SIGN_EXT=server_cert
. ../_sign_helper.sh
###
# 创建新的中级认证机构
###
# CA文件夹目录
CA_HOME="$HOME"/.ssh/ca
# 私钥密码文件(简单起见使用相同的密码)
PASS_FILE="$HOME"/.ssh/ca/.keypass
# 当前CA文件夹目录(该变量方便脚本重用)
CA_HOME="$CA_HOME"/root
# CA配置文件
CA_CFG="$CA_HOME"/openssl.cnf
# CA证书路径
CA_CERT="$CA_HOME"/certs/ca.pem.crt
IDENTITY=${IDENTITY:-intermediate}
OUTDIR=generate/"$IDENTITY"
PRIK_FILE=${PRIK_FILE:-"$OUTDIR"/"$IDENTITY".key.rsa}
PRIK_PASS=${PRIK_PASS:-file:"$PASS_FILE"}
CSR_FILE=${CSR_FILE:-"$OUTDIR"/"$IDENTITY".pem.csr}
CERT_FILE="$OUTDIR"/"$IDENTITY".pem.crt
PKCS12_FILE="$OUTDIR"/"$IDENTITY".p12
EXT_FILE=openssl.cnf
SIGN_EXT=v3_intermediate_ca
. ../_sign_helper.sh
# The main section is named req because the command we are using is req
# (openssl req ...)
[ req ]
# This specifies the default key size in bits. If not specified then 512 is
# used. It is used if the -new option is used. It can be overridden by using
# the -newkey option.
default_bits = 2048
# This is the default filename to write a private key to. If not specified the
# key is written to standard output. This can be overridden by the -keyout
# option.
default_keyfile = localhost.rsa.key
# If this is set to no then if a private key is generated it is not encrypted.
# This is equivalent to the -nodes command line option. For compatibility
# encrypt_rsa_key is an equivalent option.
encrypt_key = no
# This option specifies the digest algorithm to use.
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# if set to the value no this disables prompting of certificate fields and just
# takes values from the config file directly. It also changes the expected
# format of the distinguished_name and attributes sections.
prompt = yes
# if set to the value yes then field values to be interpreted as UTF8 strings,
# by default they are interpreted as ASCII. This means that the field values,
# whether prompted from a terminal or obtained from a configuration file, must
# be valid UTF8 strings.
utf8 = yes
# This specifies the section containing the distinguished name fields to
# prompt for when generating a certificate or certificate request.
distinguished_name = req_distinguished_name
# this specifies the configuration file section containing a list of extensions
# to add to the certificate request. It can be overridden by the -reqexts
# command line switch. See the x509v3_config(5) manual page for details of the
# extension section format.
req_extensions = req_ext
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
commonName = Common Name
emailAddress = Email Address
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
# Optionally, specify some defaults.
commonName_default = localhost
emailAddress_default = s1131234@gmail.com
countryName_default = CN
stateOrProvinceName_default = Shanghai
localityName_default = Shanghai
0.organizationName_default = enihsyou Ltd
organizationalUnitName_default = enihsyou Ltd Server Group
[ req_ext ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
keyUsage = critical, digitalSignature, keyEncipherment
subjectAltName = @alternate_names
extendedKeyUsage = serverAuth
[ alternate_names ]
IP.1 = 127.0.0.1
IP.2 = 192.168.9.4
DNS.1 = enihsyou-MacBook-Pro.local
DNS.2 = localhost
DNS.3 = hdfs-namenode
DNS.4 = yarn-resource-manager
# OpenSSL root CA configuration file.
# https://jamielinux.com/docs/openssl-certificate-authority/index.html
# https://www.phildev.net/ssl/opensslconf.html
[ ca ]
# `man ca`
default_ca = CA_default
[ CA_default ]
# Directory and file locations.
dir = /Users/enihsyou/.ssh/ca/root
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand
# The root key and root certificate.
private_key = $dir/private/ca.key.rsa
certificate = $dir/certs/ca.pem.crt
# For certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/ca.crl.pem
crl_extensions = crl_ext
default_crl_days = 30
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 365
preserve = no
policy = policy_strict
unique_subject = no
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
# Unsed to create self-signed certificates
x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
commonName = Common Name
emailAddress = Email Address
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
# Optionally, specify some defaults.
commonName_default = enihsyou Ltd Intermediate CA
emailAddress_default = s1131234@gmail.com
countryName_default = CN
stateOrProvinceName_default = Shanghai
localityName_default = Shanghai
0.organizationName_default = enihsyou Ltd
organizationalUnitName_default = enihsyou Ltd Certificate Authority
[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier = keyid:always
[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
# OpenSSL intermediate CA configuration file.
# https://jamielinux.com/docs/openssl-certificate-authority/index.html
# https://www.phildev.net/ssl/opensslconf.html
[ ca ]
# `man ca`
default_ca = CA_default
[ CA_default ]
# Directory and file locations.
dir = /Users/enihsyou/.ssh/ca/intermediate
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand
# The root key and root certificate.
private_key = $dir/private/intermediate.key.rsa
certificate = $dir/certs/intermediate.pem.crt
# For certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/intermediate.crl
crl_extensions = crl_ext
default_crl_days = 30
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 90
preserve = no
policy = policy_loose
unique_subject = no
copy_extensions = copy
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
x509_extensions = server_cert
# Extension to add when the -req option is used.
req_extensions = server_cert
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
commonName = Common Name
emailAddress = Email Address
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
# Optionally, specify some defaults.
commonName_default = localhost
emailAddress_default = s1131234@gmail.com
countryName_default = CN
stateOrProvinceName_default = Shanghai
localityName_default = Shanghai
0.organizationName_default = enihsyou Ltd
organizationalUnitName_default = enihsyou Ltd Server Group
[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA\Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment