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 " $@ "