how to generate self-signed certificates
When developing, we may need to use certificate. Instead of using Let’s Encrypt or even pay for one,
we can use openssl
& keytool
command line to generate self-signed certificates.
#!/usr/bin/env bash
#######################################################
# This scripts is used to generate the rootCA and the #
# user bi-keys #
#######################################################
set -e
rootca_home="./root_ca"
validity=36500
out="$(pwd)"
name="localhost"
subject="/C=FR/ST=IDF/L=Paris/O=Foobar/OU=Engineering/CN="
password="super-secret-password"
show_help() {
cat << EOF
Generate certificate
Usage: ${0##*/} <flags> <args>
Examples:
# Generate RSA bi-keys
${0##*/} rsa
# Create certificate with name "some.domain.name"
${0##*/} --name "some.domain.name" rsa
# Using all flags
${0##*/} -n "some.domain.name" -s "/C=FR/ST=IDF/L=Paris/O=Foobar/OU=Engineering/CN=" -o "\$(pwd)/certificates" -p "S3cR3t" rsa
Available commands:
rsa Generate CRT, KEY, P12 and JKS files with RSA algorithm
ecdsa Generate CRT and KEY files with ECDSA algorithm
Flags:
-h, --help Display help
-n, --name Certificate name (default: ${name})
-s, --subject Certificate subject (default: ${subject})
-o, --out Output directory (default: ${out})
EOF
}
info() {
echo -e "\033[0;36mINFO: ${1}\033[0m"
}
generate_root_ca() {
local folder="${out}/${rootca_home}"
if [ ! -d "${folder}" ]; then
info "Generating the Certification Authority"
mkdir -p "${folder}"
# Since we do not have any certification authority, we will generate our own.
openssl genrsa -out "${folder}/rootCA.key" 2048
openssl req -new -nodes -x509 \
-days ${validity} \
-key "${folder}/rootCA.key" \
-out "${folder}/rootCA.pem" \
-subj "${subject}rootca"
fi
}
generate_rsa() {
local certificate_name=$1
local folder="${out}/${certificate_name}"
local rootca_folder="${out}/${rootca_home}"
clean_folder "${certificate_name}" "rsa"
info "${certificate_name} - Generate RSA private key"
openssl genrsa -out "${folder}/${certificate_name}.rsa.key" 2048
generate_self_signed_certificate "${certificate_name}" rsa
info "${certificate_name} - Generate certificate signing request for our RSA certificate"
openssl req -new \
-key "${folder}/${certificate_name}.rsa.key" \
-out "${folder}/${certificate_name}.rsa.csr" \
-subj "${subject}${certificate_name}"
info "${certificate_name} - Sign the RSA CSR using CA root key"
openssl x509 -req \
-in "${folder}/${certificate_name}.rsa.csr" \
-CA "${rootca_folder}/rootCA.pem" \
-CAkey "${rootca_folder}/rootCA.key" \
-CAcreateserial \
-out "${folder}/${certificate_name}.rsa.crt" \
-days ${validity} \
-sha256
}
generate_ecdsa() {
local certificate_name=$1
local folder="${out}/${certificate_name}"
local rootca_folder="${out}/${rootca_home}"
clean_folder "${certificate_name}" "ecdsa"
info "${certificate_name} - Generate ECDSA private key"
openssl ecparam -name prime256v1 -genkey -out "${folder}/${certificate_name}.ecdsa.key"
generate_self_signed_certificate "${certificate_name}" ecdsa
info "${certificate_name} - Generate certificate signing request for our ECDSA certificate"
openssl req -new -nodes \
-key "${folder}/${certificate_name}.ecdsa.key" \
-out "${folder}/${certificate_name}.ecdsa.csr" \
-subj "${subject}${certificate_name}"
info "${certificate_name} - Sign the RSA CSR using CA root key"
openssl x509 -req \
-in "${folder}/${certificate_name}.ecdsa.csr" \
-CA "${rootca_folder}/rootCA.pem" \
-CAkey "${rootca_folder}/rootCA.key" \
-CAcreateserial \
-out "${folder}/${certificate_name}.ecdsa.crt" \
-days ${validity} \
-sha256
}
generate_p12() {
local certificate_name=$1
local folder="${out}/${certificate_name}"
local rootca_folder="${out}/${rootca_home}"
info "${certificate_name} - Generate the P12 with password '${password}'"
openssl pkcs12 -export \
-in "${folder}/${certificate_name}.rsa.crt" \
-inkey "${folder}/${certificate_name}.rsa.key" \
-out "${folder}/${certificate_name}.rsa.p12" \
-password "pass:${password}"
}
generate_self_signed_certificate() {
local certificate_name=$1
local certificate_type=$2
local folder="${out}/${certificate_name}"
info "${certificate_name}.${certificate_type} - Generate self-signed certificate"
openssl req -new -x509 \
-days ${validity} \
-key "${folder}/${certificate_name}.${certificate_type}.key" \
-out "${folder}/${certificate_name}.self-signed.${certificate_type}.crt" \
-subj "${subject}${certificate_name}"
}
clean_folder() {
local certificate_name=$1
local certificate_type=$2
local folder="${out}/${certificate_name}"
info "${certificate_name} - Delete existing ${certificate_type} files"
mkdir -p "${folder}"
if [ -f "${folder}/${certificate_name}.${certificate_type}.crt" ]; then
for f in ${folder}/*.${certificate_type}.*; do
rm "${f}"
done
fi
}
main() {
# Flags in bash tutorial here: /usr/share/doc/util-linux/examples/getopt-parse.bash
TEMP=$(getopt -o 'hn:s:p:o:' --long 'help,name:,subject:,password:,out:' -n "${0##*/}" -- "$@")
eval set -- "$TEMP"
unset TEMP
while true; do
case "${1}" in
'-h'|'--help')
show_help
exit
;;
'-n'|'--name')
name="${2}"
shift 2
continue
;;
'-s'|'--subject')
subject="${2}"
shift 2
continue
;;
'-p'|'--password')
password="${2}"
shift 2
continue
;;
'-o'|'--out')
out="${2}"
shift 2
continue
;;
'--')
shift
break
;;
*)
break
;;
esac
shift
done
case "${1}" in
'rsa')
generate_root_ca
generate_rsa "${name}"
generate_p12 "${name}"
info "Certificate generation FINISHED!!!"
;;
'ecdsa')
generate_root_ca
generate_ecdsa "${name}"
info "Certificate generation FINISHED!!!"
;;
'p12')
generate_root_ca
;;
*)
show_help
;;
esac
}
main "$@"