Suresh's Tech Notes 1.0 Help

Security & Certificates

OpenSSL & Keytool

  • Extract Certificate from Server

# Extract the server certificates. $ echo -n | openssl s_client -showcerts -connect google.com:443 \ | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > google.pem # OR use java keytool $ keytool -printcert -rfc -sslserver google.com:443 > google.pem # Show full cert chain (CN, SAN and Expiry) of TLS server $ echo | openssl s_client -showcerts -connect google.com:443 2>/dev/null \ | while openssl x509 -noout \ -subject -ext subjectAltName -issuer -dates \ -fingerprint -sha256 -serial 2>/dev/null; \ do echo "--------------" ; done # Show just the cert details of a TLS server $ echo | openssl s_client -showcerts -connect google.com:443 2>/dev/null \ | openssl x509 -inform pem -noout -text # Show full cert chain of PEM $ cat cert.pem | while openssl x509 -noout \ -subject -ext subjectAltName -issuer -dates \ -fingerprint -sha256 -serial 2>/dev/null; \ do echo "**************" ; done $ keytool -printcert -file cert.pem \ | grep -i -e "Owner" -e "Issuer:" -e "Serial number:" -e "SHA256:" # Extract TLS public keys in Cert pinning format $ openssl s_client -connect 'dns.google.com:443' 2>&1 < /dev/null \ | sed -n '/-----BEGIN/,/-----END/p' \ | openssl x509 -noout -pubkey \ | openssl asn1parse -noout -inform pem -out /dev/stdout \ | openssl dgst -sha256 -binary \ | openssl base64 $ curl -vvI https://google.com 2>&1 | grep -i date
  • Create PKCS#12 trust-store from pem

# Create/Add trust store $ keytool -importcert \ -trustcacerts \ -alias globalsign-rootca \ -storetype PKCS12 \ -keystore globalsign-rootca.p12 \ -storepass changeit \ -file globalsign.crt # Add intermediate certs (Optional) $ keytool -importcert \ -keystore globalsign-rootca.p12 \ -alias CA-intermediate \ -storepass changeit \ -file CA-intermediate.cer # Create PKCS12 truststore using OpenSSL $ openssl pkcs12 -export \ -jdktrust anyExtendedKeyUsage \ -nokeys \ -in server.pem \ -password pass: \ -out truststore-openssl.p12 # Show PKCS#12 info. $ openssl pkcs12 -info -password pass:changeit -in globalsign-rootca.p12 $ keytool -list \ -keystore globalsign-rootca.p12 \ --storetype pkcs12 \ -storepass changeit \ -v # OpenSSL: Create a new PKCS#12 store from certs $ openssl pkcs12 -export -chain -out keystore.p12 \ -inkey private.key -password pass:test123 \ -in client.crt -certfile client.crt \ -CAfile cacert.crt -caname root-ca \ -name client-key # Convert a PEM certificate file to PKCS#12 without private key. $ openssl pkcs12 -export -nokeys -in certificate.pem -out keystore.p12 # Change the keystore password # Convert PKCS#12 to PEM (don't encrypt private keys) $ openssl pkcs12 -in keystore.p12 -out keystore.pem -nodes # Export to PKCS#12 with new password $ openssl pkcs12 -export -in keystore.pem -nodes -out keystore.p12 # Verify if a Private Key Matches a Certificate $ openssl x509 -noout -modulus -in cert.pem | openssl md5 $ openssl rsa -noout -modulus -in cert.key | openssl md5
  • Extract certs from PKCS#12

# Client Certificate (Remove "-clcerts" to include intermediate/root certs) $ openssl pkcs12 -in keystore.p12 -nodes -clcerts -nokeys -passin pass:<password> -out client.crt # Certificate Key (Remove "-nodes" for encrypted) $ openssl pkcs12 -in keystore.p12 -nodes -nocerts -passin pass:<password> -out client.key # Decrypt Key $ openssl rsa -in client-encrypted.key -passin pass:<password> -out client.key # CA cert $ openssl pkcs12 -in keystore.p12 -nodes -nokeys -cacerts -passin pass:<password> -out cacert.crt # Remove attribtes (Optional) # openssl pkcs12 -in keystore.p12 -nodes -nokeys -passin pass:<password> | openssl x509 -out client.crt # openssl pkcs12 -in keystore.p12 -nodes -nocerts -passin pass:<password> | openssl rsa -out client.key # openssl pkcs12 -in keystore.p12 -nodes -nokeys -cacerts -passin pass:<password> | openssl x509 -out cacert.crt # Convert to PKCS8 private key (For java) $ openssl pkcs8 -topk8 -inform PEM -outform DER -in cert.pem -out out.pem -nocrypt
  • PEM to single line

$ awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' cert.pem > cert.cer # Revert singleline to multiline $ echo -ne $(cat cert.cer) # Check if the reverted format is ok $ echo -ne $(cat cert.cer) | openssl rsa -check
  • Show all certs from System truststore

# Using Openssl (CentOS/Ubuntu) $ while openssl x509 -noout -subject -issuer -dates; do echo ........... ; done < $(find -L /etc/ssl/certs -regex ".*/ca-\(bundle\|certificates\).crt") 2>/dev/null | grep -i subject # Using java keytool $ keytool -printcert -file /etc/ssl/certs/ca-bundle.crt \ | grep -i -e "Owner" -e "Issuer:" -e "Serial number:" -e "SHA256:"

OpenJDK

  • List all JDK cacerts using OpenSSL

    # Since JDK 18, cacert migrated to Password-Less PKCS12(https://jdk.java.net/18/release-notes#JDK-8275252) $ openssl pkcs12 \ -cacerts \ -chain \ -nokeys \ -nomacver \ -in "$(find -L $JAVA_HOME -name cacerts)" \ -passin pass: | grep -i "subject="
  • Show all JDK CA Certs using Keytool

    # JDK 17+ $ keytool -list -rfc -cacerts # Or using cacerts location. $ JDK_CACERT="$(find -L "${JAVA_HOME:-$(dirname $(readlink -f "$(which java)"))/..}" -name cacerts -print -quit)" $ keytool -list \ -rfc \ -storetype pkcs12 \ -storepass changeit \ -keystore "${JDK_CACERT}" # Older JDKs $ keytool -list \ -storetype jks \ -storepass changeit \ -keystore "${JDK_CACERT}"
  • Use Mac System truststore in Java

    $ java -Djavax.net.ssl.trustStoreType=KeychainStore \ -Djavax.net.ssl.trustStore=/Library/Keychains/System.keychain \ -jar app.jar

Self Signed Certs

Using OpenSSL

$ openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \ -keyout example.key -out example.pem \ -subj "/C=US/ST=CA/L=SanJose/O=Company Name/OU=Org/CN=www.example.com" \ -addext "subjectAltName=DNS:example.com,DNS:www.example.net,IP:10.0.0.1" # For ECC $ openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:secp384r1 -days 3650 \ -nodes -keyout example.key -out example.pem -subj "/CN=localhost" \ -addext "subjectAltName=DNS:example.com,DNS:*.example.com,IP:127.0.0.1" # See certificate details (in text format, no cert output) $ openssl x509 -in example.pem -text -noout # Instead of text form, just print subject/issuer/dates $ openssl x509 -in example.pem -noout -subject -ext subjectAltName -issuer -dates -fingerprint # Show SAN entries $ openssl x509 -text -in example.pem -noout | grep -A1 'Subject Alternative Name' $ openssl x509 -text -noout -in example.pem -certopt no_subject,no_header,no_version,no_serial,no_signame,no_validity,no_issuer,no_pubkey,no_sigdump,no_aux # Show public key of a cert $ openssl x509 -in example.pem -pubkey -noout # Get public key from a private key $ openssl pkey -check -in example.key -pubout -outform PEM # Check if the private key belongs to the cert $ diff <(openssl x509 -pubkey -in example.pem -noout) <(openssl pkey -check -in example.key -pubout -outform PEM) # OR create a test TLS server that will verify that a key and certificate match $ openssl s_server -accept 443 -www -key example.key -cert example.pem

Using OpenJDK Keytool

# Generate self signed cert $ keytool -genkeypair \ -keyalg RSA \ -keysize 4096 \ -sigalg SHA256withRSA \ -alias server \ -storetype JKS \ -keystore keystore.jks \ -storepass changeit \ -keypass changeit \ -dname "CN=localhost, OU=app, O=app, L=Unspecified, ST=Unspecified, C=US" \ -ext "SAN=dns:test.server.com,ip:127.0.0.1" \ -validity 7200 # Migrate from JKS to PKCS12 $ keytool -importkeystore \ -srckeystore keystore.jks \ -srcstoretype JKS \ -srcstorepass changeit \ -destkeystore keystore.p12 \ -deststoretype PKCS12 \ -deststorepass changeit # List cert entries $ keytool -keystore keystore.jks -storepass changeit -list -v

Add CACerts

  • To JDK Truststore

    #!/usr/bin/env bash certs=("https://pki.service.com/cacert1.crt" "https://pki.service.com/cacert2.crt") JDK_CACERT="$(find -L "${JAVA_HOME:-$(dirname $(readlink -f "$(which java)"))/..}" -name cacerts -print -quit)" echo "Using JDK CACert: ${JDK_CACERT}" pushd /tmp >/dev/null || exit 1 for cert in "${certs[@]}"; do echo "Downloading $cert ..." cert_file="$(basename "$cert")" curl -fsSL "$cert" -o "${cert_file}" echo "Installing ${cert_file} ..." keytool -importcert \ -noprompt \ -trustcacerts \ -file "${cert_file}" \ -alias "${cert_file}" \ -keystore "${JDK_CACERT}" \ -storepass changeit rm -f "${cert_file}" done popd >/dev/null || exit 1

cURL: Auth/Mutual TLS

# mTLS Authentication using PKCS#12 bundle $ curl -v \ --cert-type P12 \ --cert ~/keystore.p12:xxxxx \ -X GET "https://my-server:443/api" # Mutual TLS using PEM files $ curl -v \ --cacert ca.pem \ --key client.key \ --cert client.pem \ --resolve "my-server:443:8.8.8.8" \ -X GET "https://my-server:443/api"

CA Certs and Certificate Transparency Logs

GPG/OpenPGP

  • Setup GPG on MacOS - IntelliJ Doc

  • GPG Key Prepare

  • GPG commands

    # GPU key files $ ~/.gnupg # Show all keys $ gpg --list-keys --keyid-format=[long|short] # List secrets keys $ gpg --list-secret-keys --keyid-format=short # Update all keys from a keyserver $ gpg --refresh-keys [--keyserver pgp.mit.edu] $ gpg --recv-key XXXXXX $ gpg --delete-key "xxx@gmail.com"
  • Renew GPG Key

    # Note: The private key can never expire # Get the key id $ gpg --list-keys --keyid-format SHORT # Comment out 'no-tty' in ~/.gnupg/gpg.conf $ gpg --edit-key C8B5XXXX $ gpg> list expire // type 1y key 1 // renew encryption subkey expire // type 1y trust save quit # Export for backup $ gpg -a --export C8B5XXXX > sureshg.gpg.public $ gpg -a --export-secret-keys C8B5XXXX > sureshg.gpg.private # Send it to key servers $ gpg --keyserver keyserver.ubuntu.com --send-keys C8B5XXXX $ gpg --keyserver pgp.mit.edu --send-keys C8B5XXXX # Update GPG key in Github $ cat sureshg.gpg.public| pbcopy $ https://github.com/settings/gpg/new
  • Change Secret Password

    $ gpg --list-secret-keys --keyid-format=short $ gpg --edit-key C8B5XXXX $ gpg> passwd

Tools

TLS Debugging

$ java -Djavax.net.debug=help MyApp # java -Djavax.net.debug=all MyApp # java -Djavax.net.debug=ssl,handshake,data,trustmanager MyApp help print the help messages expand expand debugging information all turn on all debugging ssl turn on ssl debugging The following can be used with ssl: record enable per-record tracing handshake print each handshake message keygen print key generation data session print session activity defaultctx print default SSL initialization sslctx print SSLContext tracing sessioncache print session cache tracing keymanager print key manager tracing trustmanager print trust manager tracing pluggability print pluggability tracing handshake debugging can be widened with: data hex dump of each handshake message verbose verbose handshake message printing record debugging can be widened with: plaintext hex dump of record plaintext packet print raw SSL/TLS packets

Misc

TrustStore

Cryptography

  • https://www.udacity.com/course/applied-cryptography--cs387

  • https://www.coursera.org/learn/crypto#syllabus

Last modified: 21 September 2024