Last active
July 29, 2026 22:25
-
-
Save saudiqbal/0bdca8c504eb584d5df257f632063f7b to your computer and use it in GitHub Desktop.
Generate self signed TLS SSL certificate with ECC ECDSA with Intermediate bash script for Chrome Firefox Safari
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Define variables | |
| SUBJECT_ROOT="/C=US/O=Saud Iqbal/CN=Saud Iqbal Root ECDSA CA" | |
| SUBJECT_INTERMEDIATE="/C=US/O=Saud Iqbal/CN=Saud Iqbal Intermediate ECDSA CA" | |
| DAYS_VALID=3650 | |
| CONFIG_FILE="leaf_ext.cfg" | |
| SUBJECT_LEAF="/" | |
| RD=$(echo "\033[01;31m") | |
| YW=$(echo "\033[33m") | |
| GN=$(echo "\033[1;92m") | |
| CL=$(echo "\033[m") | |
| BFR="\\r\\033[K" | |
| HOLD="${YW}+${CL}" | |
| CM="${GN}✓${CL}" | |
| CROSS="${RD}✗${CL}" | |
| msg_ok() { | |
| local msg="$1" | |
| echo -e "${BFR} ${CM} ${GN}${msg}${CL}" | |
| } | |
| msg_error() { | |
| local msg="$1" | |
| echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" | |
| } | |
| msg_info() { | |
| local msg="$1" | |
| echo -e " ${HOLD} ${YW}${msg}${CL}" | |
| } | |
| msg_info "--------------------------------------" | |
| msg_info "- Self Signed Certificate Generator --" | |
| msg_info "--------------------------------------" | |
| # Root CA | |
| function GenerateRootPair() { | |
| mkdir -p root/{certs,private} | |
| echo -e "\033[0;41m Generate the Root Pair \033[m" | |
| # Generate Root Private Key: | |
| openssl ecparam -genkey -name prime256v1 -out root/private/rootCA.key.pem | |
| # Generate Self-Signed Root Certificate (10 years): | |
| openssl req -x509 -new -nodes -key root/private/rootCA.key.pem -sha256 -days "$DAYS_VALID" -out root/certs/rootCA.crt -subj "$SUBJECT_ROOT" | |
| msg_ok "Root pair setup done!" | |
| sleep 1 | |
| } | |
| # Intermediate CA | |
| function GenerateIntermediatePair() { | |
| mkdir -p intermediate/{certs,private,csr} | |
| echo -e "\033[0;41m Generate Intermediate Certificate \033[m" | |
| # Generate Intermediate Private Key: | |
| openssl ecparam -genkey -name prime256v1 -out intermediate/private/intermediateCA.key.pem | |
| # Generate Intermediate CSR: | |
| openssl req -new -key intermediate/private/intermediateCA.key.pem -out intermediate/csr/intermediateCA.csr -subj "$SUBJECT_INTERMEDIATE" | |
| # Sign the Intermediate with the Root CA: | |
| rootexpirationdate=$(( ( $(date -d "$(openssl x509 -in root/certs/rootCA.crt -noout -enddate | cut -d= -f2-)" +%s) - $(date +%s) ) / 86400 )) | |
| rootexpirationdate=$((rootexpirationdate - 1)) | |
| openssl x509 -req -in intermediate/csr/intermediateCA.csr -CA root/certs/rootCA.crt -CAkey root/private/rootCA.key.pem -CAcreateserial -out intermediate/certs/intermediateCA.crt -days "$rootexpirationdate" -sha256 -extfile <(echo -e "basicConstraints=critical,CA:TRUE\nkeyUsage=critical,digitalSignature,cRLSign,keyCertSign") | |
| msg_ok "Intermediate CA setup done!" | |
| sleep 1 | |
| } | |
| # Leaf Certificate | |
| function GenerateLeafPair() { | |
| mkdir -p leaf/{newcerts,private,csr} | |
| echo -e "\033[0;41m Generate Leaf Certificate \033[m" | |
| echo -n "Enter hostname for creating new leaf certificate: " | |
| read DOMAIN | |
| if [[ -n $DOMAIN ]]; then | |
| #Generate Leaf Private Key: | |
| openssl ecparam -genkey -name prime256v1 -out leaf/private/${DOMAIN}.leaf.key.pem | |
| #Generate Leaf CSR: | |
| openssl req -new -key leaf/private/${DOMAIN}.leaf.key.pem -out leaf/csr/${DOMAIN}.leaf.csr -subj "$SUBJECT_LEAF" | |
| # Create a temporary config file to handle Subject Alternative Names (SAN) | |
| cat > "$CONFIG_FILE" <<EOF | |
| #authorityKeyIdentifier=keyid,issuer | |
| basicConstraints=critical,CA:FALSE | |
| keyUsage=critical,digitalSignature | |
| extendedKeyUsage=serverAuth | |
| subjectAltName=critical,@alt_names | |
| [alt_names] | |
| DNS.1 = $DOMAIN | |
| EOF | |
| rootexpirationdate=$(( ( $(date -d "$(openssl x509 -in root/certs/rootCA.crt -noout -enddate | cut -d= -f2-)" +%s) - $(date +%s) ) / 86400 )) | |
| rootexpirationdate=$((rootexpirationdate - 1)) | |
| # Note: Using keyid,issuer in authorityKeyIdentifier creates an explicit chain recognized by Chrome's certificate verification engine.Sign the certificate using the intermediate key: | |
| openssl x509 -req -in leaf/csr/${DOMAIN}.leaf.csr -CA intermediate/certs/intermediateCA.crt -CAkey intermediate/private/intermediateCA.key.pem -CAcreateserial -out leaf/newcerts/${DOMAIN}.leaf.crt -days "$rootexpirationdate" -sha256 -extfile leaf_ext.cfg | |
| cat leaf/newcerts/${DOMAIN}.leaf.crt intermediate/certs/intermediateCA.crt root/certs/rootCA.crt > leaf/newcerts/${DOMAIN}.fullchain.pem | |
| msg_ok "Leaf CA setup done!" | |
| # Clean up the configuration file | |
| rm "$CONFIG_FILE" | |
| else | |
| msg_error "No response received!" | |
| fi | |
| sleep 1 | |
| } | |
| if [ -d "root" ]; then | |
| msg_info "Root CA found, using it for leaf certificate!" | |
| else | |
| printf 'Generate the Root Pair [y/N]? ' | |
| read answer | |
| if [ "$answer" != "${answer#[Yy]}" ] ;then | |
| GenerateRootPair | |
| fi | |
| fi | |
| if [ -d "intermediate" ]; then | |
| msg_info "Intermediate CA found, using it for leaf certificate!" | |
| else | |
| printf 'Generate Intermediate Certificate [y/N]? ' | |
| read answer | |
| if [ "$answer" != "${answer#[Yy]}" ] ;then | |
| GenerateIntermediatePair | |
| fi | |
| fi | |
| printf 'Generate New Leaf Certificate [y/N]? ' | |
| read answer | |
| if [ "$answer" != "${answer#[Yy]}" ] ;then | |
| GenerateLeafPair | |
| fi | |
| msg_info "--------------------------------------" | |
| msg_info "- Self Signed Certificate Setup Done -" | |
| msg_info "--------------------------------------" | |
| exit 0 |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Save the bash script as
tls-int-ecdsa.sh, change the names and and run it.Your newly generated certificate for hostname should be in
leaf/newcerts/and private key inleaf/private/Import the newly generated
/root/certs/rootCA.crtinto your browser