====== SSL-Schlüssel generieren ====== * [[https://wiki.openssl.org/]] * [[https://wiki.openssl.org/index.php/Command_Line_Utilities]] * [[https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations]] * [[https://www.thomas-krenn.com/de/wiki/TCP_Port_443_(https)_Zugriff_mit_openssl_%C3%BCberpr%C3%BCfen|Zugriff auf HTTPS mit openssl überprüfen]]: > openssl s_client -connect www.heise.de:https **[[::EDV:einen selbst signierten SSL-Schlüssel generieren (RSA)]]** ==== mit einem einzigen Aufruf einen neuen Schlüssen und sein Zertifikat erzeugen ==== **''RSA (16384 Bit)''**: > openssl req -rand /dev/urandom -new -x509 -newkey rsa:16384 -sha3-512 -nodes -keyout /usr/local/etc/ssl/key.pem -keyform PEM -out /usr/local/etc/ssl/crt.pem -outform PEM -days 7000 -subj "/emailAddress=email@adresse.de/C=DE/ST=Hessen/L=Frankfurt/O=Firma/OU=Abteilung/CN=Hostname" > openssl rsa -in /usr/local/etc/ssl/key.pem -out /usr/local/etc/ssl/public.pem -outform PEM -pubout **''ED448''**-//[[http://ed448goldilocks.sourceforge.net/|Goldlöckchen]]// (224-Bit): > openssl req -rand /dev/urandom -new -x509 -newkey ED448 -sha3-512 -nodes -keyout /usr/local/etc/ssl/key.pem -keyform PEM -out /usr/local/etc/ssl/crt.pem -outform PEM -days 7000 -subj "/emailAddress=email@adresse.de/C=DE/ST=Hessen/L=Frankfurt/O=Firma/OU=Abteilung/CN=Hostname" > openssl pkey -in /usr/local/etc/ssl/key.pem -out /usr/local/etc/ssl/public.pem -outform PEM -pubout **''ED25519''** (128-Bit): > openssl req -rand /dev/urandom -new -x509 -newkey ED25519 -sha3-512 -nodes -keyout /usr/local/etc/ssl/key.pem -keyform PEM -out /usr/local/etc/ssl/crt.pem -outform PEM -days 7000 -subj "/emailAddress=email@adresse.de/C=DE/ST=Hessen/L=Frankfurt/O=Firma/OU=Abteilung/CN=Hostname" > openssl pkey -in /usr/local/etc/ssl/key.pem -out /usr/local/etc/ssl/public.pem -outform PEM -pubout Die DSA-Schlüssel sind alle NSA-optimiert und somit als unsicher anzusehen. Auch von den Schlüsseln mit elliptischen Kurven wird vermutet, dass sie NSA-optimiert sind. Weiterhin gilt die Einschränkung, dass bei den Algorithmen, die auf elliptischen Kurven basieren, die Schlüssellänge nicht konfigurierbar ist. Auch wenn von RSA nicht vermutet wird, das es NSA-optimiert ist, so arbeitet RSA doch deterministisch und ist deshalb unter Umständen für bestimmte Angriffe anfällig. In der Praxis wird RSA daher mit dem "Optimal Asymmetric Encryption Padding" kombiniert. Daraus ergibt sich, dass ein RSA-Algorithmus, der Padding verwendet, grundsätzlich als sicherer einzustufen ist als alle anderen genannten Algorithmen. Ein 160 Bit langer Schüssel, der auf elliptischen Kurven basieren (ECDH), gilt als ähnlich sicher wie ein 1024 Bit langer RSA-Schlüssel (RSA/DH): 160 Bit ECDH - 1024 Bit RSA/DH 224 Bit ECDH - 2048 Bit RSA/DH 256 Bit ECDH - 3072 Bit RSA/DH 384 Bit ECDH - 7680 Bit RSA/DH ECDH-Schlüssel eignet sich daher besonders dann, wenn die Speicher- oder Rechenkapazität begrenzt ist, z. B. in Smartcards oder anderen eingebetteten Systemen. ===== Elliptische Kurve (OpenSSL 1.0.1j-freebsd) ===== * [[https://crypto.stackexchange.com/questions/67457/elliptic-curve-ed25519-vs-ed448-differences|Elliptic curve ed25519 vs ed448 - Differences]] * [[http://wiki.ubuntuusers.de/Apache/SSL]] erst einen neuen Schlüssen mit elliptischen Kurven erstellen und dann sein Zertifikat erzeugen: openssl ecparam -list_curves openssl ecparam -out /usr/local/etc/apache24/server.key -name secp256k1 -genkey openssl req -new -x509 -key /usr/local/etc/apache24/server.key -keyform PEM -out /usr/local/etc/apache24/server.crt -outform PEM -days 7000 -subj "/emailAddress=email@adresse.de/C=DE/ST=Hessen/L=Frankfurt/O=Firma/OU=Abteilung/CN=Hostname" ===== Beschreibung (PEM) ===== === privater Schlüssel === *.key -----BEGIN RSA PRIVATE KEY----- ... -----END RSA PRIVATE KEY----- === Zertifikat (öffentlicher Schlüssel) === *.crt -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- === Anfrage zur Zertifikatssignierung (enthält das Zertifikat) === *.csr -----BEGIN CERTIFICATE REQUEST----- ... -----END CERTIFICATE REQUEST----- === alle Zertifikate aus der PEM-Datei separat rausschreiben === **//Das ist jetzt nicht mehr nötig, aktuelle OpenSSL-Versionen können problemlos mit PEM-Dateien umgehen.//** > vi PEM2CRT.sh #!/bin/bash # # Dieses Skript schreibt alle Zertifikate aus einer PEM-Datei # in einzelne CRT-Dateien, damit man sie mit openssl leichter # überprüfen kann. # VERSION="v2014012000" if [ -z "${1}" ] ; then echo "${0} zertifikatsdateiname.pem" exit 1; else PEMDATEI="${1}" fi NR=0 cat "${PEMDATEI}" | while read ZEILE do if [ "${ZEILE}" == "-----BEGIN CERTIFICATE-----" ] ; then SCHREIBEN="Ja" NR="$(echo "${NR}" | awk '{print $1 + 1}')" #echo "Start: Zertifikat_${NR}.crt" rm -f "Zertifikat_${NR}.crt" echo "Zertifikat_${NR}.crt" fi if [ "${SCHREIBEN}" == "Ja" ] ; then echo "${ZEILE}" >> Zertifikat_${NR}.crt fi if [ "${ZEILE}" == "-----END CERTIFICATE-----" ] ; then #echo "ENDE: Zertifikat_${NR}.crt" SCHREIBEN="Nein" fi done #ls -l Zertifikat_*.crt > vi CRT-Check.sh #!/bin/bash # # Dieses Skript gibt den CN eines Zertifikates aus, # welches in einer PAM-Datei steckt. # Sind in der PEM-Datei mehrere Zertifikate enthalten, # dann wird der CN von jedem einzelnen ausgegeben. # VERSION="v2014012000" PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" MEINVERZ="$(dirname "${0}")" if [ -z "${1}" ] ; then echo "${0} www.domain.de.pem" exit 1; else PEMDATEI="${1}" fi ${MEINVERZ}/PEM2CRT.sh "${PEMDATEI}" | while read DATEI do sync if [ -r "${DATEI}" ] ; then CN="$(openssl x509 -noout -text -in "${DATEI}" | grep -F 'Subject:' | grep -F ' CN=' | sed 's/^.*[ ]CN[=]//')" echo "'${DATEI}' -> '${CN}'" fi done Beide Dateien müssen im selben Verzeichnis liegen! ===== Zugehörigkeiten verifizieren ===== Will man wissen, ob z.B. ein Zertifikat zu einem Schlüssel gehört, dann kann man das so überprüfen: # openssl rsa -noout -modulus -in domain.de.key | openssl md5 0d35e7c7e4db8c07fff78dd4c3de17f1 # openssl req -noout -modulus -in domain.de.csr | openssl md5 0d35e7c7e4db8c07fff78dd4c3de17f1 # openssl x509 -noout -modulus -in domain.de.crt | openssl md5 0d35e7c7e4db8c07fff78dd4c3de17f1 Wenn alle Checksummen identisch sind, dann gehören alle Dateien zusammen. ===== Schlüssel und Zertifikat überprüfen ===== ==== Der Schlüssel, die Zertifikatsanfrage und das Zertifikat befinden sich in jeweils einzelnen Dateien ==== nachsehen, was im RSA-Schlüssel steht: > openssl rsa -noout -text -in domain.de.key Private-Key: (4096 bit) ... nachsehen, was in der Zertifikatsanfrage steht: > openssl req -noout -text -in domain.de.csr nachsehen, was im Zertifikat steht: > openssl x509 -noout -text -in domain.de.crt nachsehen, mit welcher Verschlüsselungs-Algorithmus verwendet wurde: > openssl x509 -noout -text -in domain.de.crt | fgrep Algorithm Signature Algorithm: sha256WithRSAEncryption Public Key Algorithm: rsaEncryption Signature Algorithm: sha256WithRSAEncryption Da das Zertifikat auf einem RSA-Schlüssel basiert, muss das folgende Kommando zur Ausgabe des Modulus aus dem Schlüssel, die Option ''RSA'' enthalten: ''openssl rsa ...''. diese Ausgaben müssen alle identische Ausgaben liefern, dann gehören sie zusammen: > openssl rsa -noout -modulus -in domain.de.key | openssl md5 > openssl req -noout -modulus -in domain.de.csr | openssl md5 > openssl x509 -noout -modulus -in domain.de.crt | openssl md5 diese Ausgabe muss anders sein, weil ihr ein anderer Schlüssel zu grunde liegt: > openssl x509 -noout -modulus -in intermediate.domain.de.crt | openssl md5 Kontrolle, ob das Zwischenzertifikat der Authentifizierungsstelle zum Zertifikat unseres Schlüssels passt: > openssl verify -CAfile intermediate.domain.de.crt domain.de.crt domain.de.crt: OK Ablaufdatum vom Zertifikat ausgeben: > openssl x509 -noout -text -in domain.de.crt | fgrep -A1 'Not After' ==== Der Schlüssel und das Zertifikat befinden sich in der selben Dateien ==== sollte man ersteinmal den Schlüssel und das Zertifikat in unterschiedliche Dateien vorliegen haben, dann kann man sie beide wie folgt zu einer einzigen PEM-Datei zusammenfühgen: > cat domain.de.key domain.de.crt > domain.de.pem > rm domain.de.key domain.de.crt nachsehen, was im RSA-Schlüssel steht: > openssl rsa -noout -text -in domain.de.pem Private-Key: (4096 bit) ... nachsehen, was in der Zertifikatsanfrage steht: > openssl req -noout -text -in domain.de.pem nachsehen, was im Zertifikat steht: > openssl x509 -noout -text -in domain.de.pem nachsehen, mit welcher Verschlüsselungs-Algorithmus verwendet wurde: > openssl x509 -noout -text -in domain.de.pem | fgrep Algorithm Signature Algorithm: sha256WithRSAEncryption Public Key Algorithm: rsaEncryption Signature Algorithm: sha256WithRSAEncryption Da das Zertifikat auf einem RSA-Schlüssel basiert, muss das folgende Kommando zur Ausgabe des Modulus aus dem Schlüssel, die Option ''RSA'' enthalten: ''openssl rsa ...''. __diese Ausgaben müssen alle identische Ausgaben liefern, dann gehören sie zusammen__: > openssl rsa -noout -modulus -in domain.de.pem | openssl md5 > openssl req -noout -modulus -in domain.de.csr | openssl md5 > openssl x509 -noout -modulus -in domain.de.pem | openssl md5 diese Ausgabe muss anders sein, weil ihr ein anderer Schlüssel zu grunde liegt: > openssl x509 -noout -modulus -in intermediate.domain.de.crt | openssl md5 __Kontrolle, ob das Zwischenzertifikat der Authentifizierungsstelle zum Zertifikat unseres Schlüssels passt__: > openssl verify -CAfile intermediate.domain.de.crt domain.de.pem domain.de.crt: OK Ablaufdatum vom Zertifikat ausgeben: > openssl x509 -noout -text -in domain.de.pem | fgrep -A1 'Not After' ===== Einzelschritte von Hand ==== Wenn Schlüssellänge egal ist und der Schlüssel keinen Passwortschutz benötigt, dann braucht man keinen Schlüssel separat erzeugen weil beim erzeugen eines Zertifikates automatisch ein Schlüssel generiert wird, wenn keiner vorhanden ist. Alle gewünschten Parameter (z.B. Schlüssellänge) müssen in der ''/etc/ssl/openssl.cnf'' gesetzt werden. ==== einen SSL-Schlüssel generieren ==== === ohne Passphrase === **Wenn man einen Schlüssel mit einer bestimmten Länge möchte:** # openssl genrsa -out server.key 4096 === mit Passphrase === **Wenn man einen mit Passwort geschützten Schlüssel möchte:** # openssl genrsa -des3 -out server.key 4096 === Passphrase entfernen === # openssl rsa < server.pem > private_key_ohne_passphrase.key ==== eine Zertifikatsanfrage (CSR) generieren ==== Wenn man bei einer öffentlichen Signierungsstelle (CA) ein signiertes Zertifikat kaufen möchte, dann braucht man die CSR-Datei: > openssl req -new -key server.key -keyform PEM -out server.csr -outform PEM -days 7000 -subj "/emailAddress=email@adresse.de/C=DE/ST=Hessen/L=Frankfurt/O=Firma/OU=Abteilung/CN=Hostname" wenn der SSL-Schlüssel gleich mit generiert werden soll, weil es noch keinen gibt: > openssl req -rand /dev/urandom -newkey rsa:4096 -sha512 -nodes -keyout server.key -keyform PEM -out server.csr -outform PEM -days 7000 -subj "/emailAddress=email@adresse.de/C=DE/ST=Hessen/L=Frankfurt/O=Firma/OU=Abteilung/CN=Hostname" === eine Zertifikatsanfrage (CSR) für ein Multi-Domain-Zertifikat generieren === [[https://www.networking4all.com/en/ssl+certificates/csr+check/|hier kann man das CSR überprüfen]] ~/bin/make_Multi-Domain-CSR_SHA2.sh -s DE -l Hessen -c Frankfurt -o 'Firma GmbH' -a Abteilung -e admin@firma.de -d www.firma.de -m 'www.betrieb.de betrieb.de www.fabrik.de fabrik.de www.werk.de werk.de www.arbeit.de arbeit.de' #!/bin/bash #------------------------------------------------------------------------------# # # hiermit können Multi-Domain-CSRs erstellt werden # #------------------------------------------------------------------------------# # # openssl req -noout -text -in w.galeria-mobil.de.csr # https://www.networking4all.com/en/ssl+certificates/csr+check/ # #------------------------------------------------------------------------------# VERSION="v2018111900" # Voreinstellungen #ZEITRAUM="365" # Gültigkeitszeitraum 1 Jahr ZEITRAUM="730" # Gültigkeitszeitraum 2 Jahre #ZEITRAUM="1095" # Gültigkeitszeitraum 3 Jahre nicht mehr möglich BITLANG="4096" # Schlüssellänge if [ -z "${1}" ] ; then echo "${0} -h" exit 1 fi while [ "${#}" -ne "0" ]; do case "${1}" in -a) ABTEILUNG=${2} # Marke shift ;; -b) BITLANG=${2} # Schlüssellänge: 4096 shift ;; -c) STADT=${2} # z.B.: Idstein shift ;; -d) DOMAIN=${2} # neuen oder vorhandenen Schlüssel verwenden shift ;; -e) EMAIL=${2} # z.B.: ssladmin@iq-optimize.de shift ;; -k) KEY=${2} # neuen oder vorhandenen Schlüssel verwenden shift ;; -l) LAND=${2} # z.B.: Hessen shift ;; -m) MULTI_DOMAIN=${2} # z.B.: ssladmin@iq-optimize.de shift ;; -o) ORGANISATION=${2} # Mandant shift ;; -s) STAAT=${2} # z.B.: DE shift ;; -z) ZEITRAUM=${2} # Gültigkeitszeitraum: 730 shift ;; -h) echo " zwingend erforderliche Parameter: -d Domain/FQDN -l Land -c City/Stadt -o Organisation/Mandant -a Abteilung/Marke optionale Parameter: -k Key-Datei der schon existiert -s Staat -m Mail -z Zeitraum der Gültigkeit -b Bit-Länge des Schlüssels Beispiele wild-card-Zertifikat mit neuem Schlüssel: # ${0} -d '*.telco.de' -l Hessen -c Maintal -o Drillisch -a telco Standard-Zertifikat mit vorhandenem Schlüssel: # ${0} -d www.telco.de -s DE -l Hessen -c Maintal -o Drillisch -a telco -k www.telco.de.key -m ssladmin@iq-optimize.de " exit 0 ;; *) if [ "$(echo "${1}"|egrep '^-')" ] ; then echo "Der Parameter '${1}' wird nicht unterstützt!" exit 1 fi shift ;; esac done ZNAME="$(echo "${DOMAIN}" | tr -s '[*]' 'w')" if [ -z "${STAAT}" -o -z "${DOMAIN}" -o -z "${LAND}" -o -z "${STADT}" -o -z "${ORGANISATION}" -o -z "${ABTEILUNG}" -o -z "${EMAIL}" ] ; then echo " Es werden alle Parameter benötigt! => ${0} -h " exit 1 fi #------------------------------------------------------------------------------# #rm -fr /tmp/Multi-Domain-CSR-Test/ #mkdir /tmp/Multi-Domain-CSR-Test/ || exit 2 #cd /tmp/Multi-Domain-CSR-Test/ || exit 3 #------------------------------------------------------------------------------# ZUFALLSWERT="$(head -c 100 /dev/urandom | base64 | tr -d '\n' | tr -cd '[:alnum:]' | cut -b-12)" CFG_DATEI="/tmp/openssl_csr_${ZUFALLSWERT}" MULTIDOMAIN="-config ${CFG_DATEI}" MD="$(NR=0 for MD in ${MULTI_DOMAIN} do NR="$(echo "${NR}" | awk '{print $1 + 1}')" echo "DNS.${NR}=${MD}" done | tr -s '\n' ',' | sed 's/[,]$//')" echo " MD=${MD} " M_DOMAINS="$(NR=0 for MD in ${MULTI_DOMAIN} do NR="$(echo "${NR}" | awk '{print $1 + 1}')" echo "DNS.${NR} = ${MD}" done)" echo " # /etc/ssl/openssl.cnf RANDFILE=/dev/urandom [ ca ] default_ca = CA_default [ CA_default ] default_days = ${ZEITRAUM} [ req ] distinguished_name = distinguished_name req_extensions = v3_req string_mask = utf8only [ distinguished_name ] emailAddress = ${EMAIL} C = ${STAAT} ST = ${LAND} L = ${STADT} O = ${ORGANISATION} OU = ${ABTEILUNG} CN = ${DOMAIN} [v3_req] keyUsage = keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @subject_alt_names [ subject_alt_names ] ${M_DOMAINS} " > ${CFG_DATEI} echo "-------------------------------------------------------------------------" cat ${CFG_DATEI} echo "-------------------------------------------------------------------------" #------------------------------------------------------------------------------# if [ -z "${KEY}" ] ; then echo "################################################################################" # neuer Schlüssel echo "openssl req -sha256 -newkey rsa:${BITLANG} -nodes -keyout ${ZNAME}.key -keyform PEM -out ${ZNAME}.csr -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}/${MD}" -config ${CFG_DATEI}" openssl req -sha256 -newkey rsa:${BITLANG} -nodes -keyout ${ZNAME}.key -keyform PEM -out ${ZNAME}.csr -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}/${MD}" -config ${CFG_DATEI} ls -lha ${CFG_DATEI} rm -f ${CFG_DATEI} else if [ -r "${KEY}" ] ; then # vorhandener Schlüssel echo "openssl req -new -key ${KEY} -keyform PEM -out ${ZNAME}.csr -outform PEM -subj \"/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}\" -config ${CFG_DATEI}" openssl req -new -key ${KEY} -keyform PEM -out ${ZNAME}.csr -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}" -config ${CFG_DATEI} ls -lha ${CFG_DATEI} rm -f ${CFG_DATEI} else echo "die Datei ${KEY} ist nicht lesbar..." exit 1 fi fi if [ -r "${ZNAME}.csr" ] ; then echo "${ZNAME}.csr $(openssl req -text -verify -in ${ZNAME}.csr)" fi if [ -r "${KEY}" ] ; then echo "${KEY} $(openssl rsa -noout -modulus -in ${KEY} | openssl md5)" fi if [ -r "${ZNAME}.csr" ] ; then echo "${ZNAME}.csr $(openssl req -noout -modulus -in ${ZNAME}.csr | openssl md5)" fi if [ -r "${ZNAME}.crt" ] ; then echo "${ZNAME}.crt $(openssl x509 -noout -modulus -in ${ZNAME}.crt | openssl md5)" fi ==== ein selbst signiertes Zertifikat (CRT) generieren ==== [[http://wiki.ubuntuusers.de/Apache/SSL]] **EC-Schlüssel (elliptic curve = Elliptische Kurve) generieren:** > openssl ecparam -list_curves **Schlüssel und Zertifikat in Standardlänge erzeugen:** > openssl req -new -x509 -nodes -keyout server.key -out server.crt -days 7000 > openssl ecparam -out /etc/ssl/private/apache.key -genkey -name secp521r1 **Schlüssel und Zertifikat mit definierter Länge (hier 4096 Bit) erzeugen:** > openssl req -rand /dev/urandom -new -x509 -newkey rsa:4096 -sha512 -nodes -keyout server.key -keyform PEM -out server.crt -outform PEM -days 7000 -subj "/emailAddress=email@adresse.de/C=DE/ST=Hessen/L=Frankfurt/O=Firma/OU=Abteilung/CN=Hostname" **Zertifikat für ein vorhandenen Schlüssel erzeugen:** > openssl req -new -x509 -key server.key -keyform PEM -out server.crt -outform PEM -days 7000 -subj "/emailAddress=email@adresse.de/C=DE/ST=Hessen/L=Frankfurt/O=Firma/OU=Abteilung/CN=Hostname" ==== letzte Schritte - Die Überprüfung ==== **damit nicht jeder ran kann:** > chmod 0600 server.* **Fingerabdruck anzeigen:** > openssl x509 -noout -fingerprint -in server.crt **Zertifikats-Ersteller -Signierer und Gültigkeitszeitraum:** > openssl x509 -noout -subject -issuer -dates -in server.crt **SSL-Schlüssellänge ausgeben:** > openssl x509 -noout -text -in server.crt | fgrep ' bit)' ===== per Skript ===== ==== einfaches Skript ==== #!/bin/bash SSLNAME="test" RECHNERNAME="$(hostname -f)" EMAIL="email@adresse.de" STAAT="DE" LAND="Hessen" STADT="Frankfurt" ORGANISATION="Firma" ABTEILUNG="Abteilung" ZEITRAUM="12000" # Gültigkeitszeitraum BITLANG="16384" # Schlüssellänge openssl req -rand /dev/urandom -sha1 -new -x509 -newkey rsa:${BITLANG} -nodes -keyout ${SSLNAME}.key -keyform PEM -out ${SSLNAME}.crt -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${RECHNERNAME}" -days ${ZEITRAUM} if [ -r "${SSLNAME}.key" ] ; then echo "${SSLNAME}.key $(openssl rsa -noout -modulus -in ${SSLNAME}.key | openssl md5)" fi if [ -r "${SSLNAME}.crt" ] ; then echo "${SSLNAME}.crt $(openssl x509 -noout -modulus -in ${SSLNAME}.crt | openssl md5)" openssl x509 -noout -subject -issuer -dates -in ${SSLNAME}.crt fi ==== Skript mit Parametern ==== Um ein Zertifikat von einer offiziellen CA signieren lassen zu können, brauchen wir eine ''*.csr''-Datei. Die ''*.csr''-Datei wird dann zur Zertifizierungsstelle geschickt, die dann das signierte Zertifikat in einer ''*.crt''-Datei zurück schicken. **''*.key''** (privater Schlüssel) und **''*.csr''** (Anfrage zum signieren des Zertifikates mit Zertifikat) erstellen: # bin/make_cert_rsa.sh -d '*.firma.de' -l Hessen -c Frankfurt -o Firma -a Abteilung nur **''*.csr''** (Anfrage zum signieren des Zertifikates mit Zertifikat) erstellen: # bin/make_cert_rsa.sh -d www.firma.de -l Hessen -c Frankfurt -o Firma -a Abteilung -k www.firma.de.key **''*.key''** (privater Schlüssel) und **''*.crt''** (unsigniertes Zertifikat -> öffentlicher Schlüssel) erstellen: # bin/make_cert_rsa.sh -d '*.firma.de' -l Hessen -c Frankfurt -o Firma -a Abteilung -u nur **''*.crt''** (unsigniertes Zertifikat -> öffentlicher Schlüssel) erstellen: # bin/make_cert_rsa.sh -d www.firma.de -l Hessen -c Frankfurt -o Firma -a Abteilung -u -k www.firma.de.key #!/bin/bash # Voreinstellungen STAAT="DE" # Staat EMAIL="default@domain.de" # eMail ZEITRAUM="731" # Gültigkeitszeitraum in Tagen BITLANG="4096" # Schlüssellänge in Bit if [ -z "${1}" ] ; then echo "${0} -h" exit 1 fi while [ "${#}" -ne "0" ]; do case "${1}" in -d) DOMAIN=${2} # neuen oder vorhandenen Schlüssel verwenden shift ;; -k) KEY=${2} # neuen oder vorhandenen Schlüssel verwenden shift ;; -u) UNSIGNIERT=JA # Schlüssel mit unsigniertem Zertifikat erstellen shift ;; -s) STAAT=${2} # z.B.: DE shift ;; -l) LAND=${2} # z.B.: Hessen shift ;; -c) STADT=${2} # z.B.: Frankfurt shift ;; -o) ORGANISATION=${2} # Organisation shift ;; -a) ABTEILUNG=${2} # Abteilung shift ;; -m) EMAIL=${2} # z.B.: default@domain.de shift ;; -z) ZEITRAUM=${2} # Gültigkeitszeitraum: 730 shift ;; -b) BITLANG=${2} # Schlüssellänge: 4096 shift ;; -h) echo " zwingend erforderliche Parameter: -d Domain/FQDN -l Land -c City/Stadt -o Organisation/Mandant -a Abteilung/Marke optionale Parameter: -k Key-Datei der schon existiert -s Staat -m Mail -z Zeitraum der Gültigkeit -b Bit-Länge des Schlüssels Beispiele wild-card-Zertifikat mit neuem Schlüssel: # ${0} -d '*.firma.de' -l Hessen -c Frankfurt -o Firma -a Abteilung unsigniertes Standard-Zertifikat mit vorhandenem Schlüssel: # ${0} -d www.firma.de -l Hessen -c Frankfurt -o Firma -a Abteilung -k www.firma.de.key -u " exit 0 ;; *) if [ "$(echo "${1}"|egrep '^-')" ] ; then echo "Der Parameter '${1}' wird nicht unterstützt!" exit 1 fi shift ;; esac done ZNAME="$(echo "${DOMAIN}" | tr -s '[*]' 'w')" if [ -z "${DOMAIN}" -o -z "${LAND}" -o -z "${STADT}" -o -z "${ORGANISATION}" -o -z "${ABTEILUNG}" ] ; then echo " Es werden mind. die Parameter -d, -l, -c, -o, und -a benötigt! => ${0} -h " exit 1 fi if [ "${UNSIGNIERT}" == "JA" ] ; then if [ -z "${KEY}" ] ; then # neuer Schlüssel KEY="${ZNAME}.key" echo "openssl req -x509 -rand /dev/urandom -sha1 -newkey rsa:${BITLANG} -nodes -keyout ${KEY} -keyform PEM -out ${ZNAME}.crt -outform PEM -subj \"/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}\" -days ${ZEITRAUM}" openssl req -x509 -rand /dev/urandom -sha1 -newkey rsa:${BITLANG} -nodes -keyout ${KEY} -keyform PEM -out ${ZNAME}.crt -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}" -days ${ZEITRAUM} else echo "openssl req -x509 -new -key ${KEY} -out ${ZNAME}.crt -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}" -days ${ZEITRAUM}" openssl req -x509 -new -key ${KEY} -out ${ZNAME}.crt -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}" -days ${ZEITRAUM} fi else if [ -z "${KEY}" ] ; then # neuer Schlüssel KEY="${ZNAME}.key" echo "openssl req -rand /dev/urandom -sha1 -newkey rsa:${BITLANG} -nodes -keyout ${KEY} -keyform PEM -out ${ZNAME}.csr -outform PEM -subj \"/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}\" -days ${ZEITRAUM}" openssl req -rand /dev/urandom -sha1 -newkey rsa:${BITLANG} -nodes -keyout ${KEY} -keyform PEM -out ${ZNAME}.csr -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}" -days ${ZEITRAUM} else if [ -r "${KEY}" ] ; then # vorhandener Schlüssel echo "openssl req -new -key ${KEY} -keyform PEM -out ${ZNAME}.csr -outform PEM -subj \"/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}\" -days ${ZEITRAUM}" openssl req -new -key ${KEY} -keyform PEM -out ${ZNAME}.csr -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}" -days ${ZEITRAUM} else echo "die Datei ${KEY} ist nicht lesbar..." exit 1 fi fi fi if [ -r "${ZNAME}.csr" ] ; then echo "${ZNAME}.csr $(openssl req -text -verify -in ${ZNAME}.csr)" fi if [ -r "${KEY}" ] ; then echo "${KEY} $(openssl rsa -noout -modulus -in ${KEY} | openssl md5)" fi if [ -r "${ZNAME}.csr" ] ; then echo "${ZNAME}.csr $(openssl req -noout -modulus -in ${ZNAME}.csr | openssl md5)" fi if [ -r "${ZNAME}.crt" ] ; then echo "${ZNAME}.crt $(openssl x509 -noout -modulus -in ${ZNAME}.crt | openssl md5)" fi #!/bin/bash VERSION="v2021101100" # Voreinstellungen / für 5G sollen (zukünftig nur noch) ecdsa-Schlüssel verwendet werden # https://www.ssl.com/how-to/manually-generate-a-certificate-signing-request-csr-using-openssl/#ftoc-heading-3 ZEITRAUM="365" # Gültigkeitszeitraum 1 Jahr BITLANG="384" # Schlüssellänge (EC) if [ -z "${1}" ] ; then echo "${0} -h" exit 1 fi while [ "${#}" -ne "0" ]; do case "${1}" in -d) DOMAIN=${2} # neuen oder vorhandenen Schlüssel verwenden shift ;; -k) KEY=${2} # neuen oder vorhandenen Schlüssel verwenden shift ;; -s) STAAT=${2} # z.B.: DE shift ;; -l) LAND=${2} # z.B.: Hessen shift ;; -c) STADT=${2} # z.B.: Idstein shift ;; -o) ORGANISATION=${2} # Mandant shift ;; -a) ABTEILUNG=${2} # Marke shift ;; -m) EMAIL=${2} # z.B.: ssladmin@iq-optimize.de shift ;; -z) ZEITRAUM=${2} # Gültigkeitszeitraum: 730 shift ;; -b) BITLANG=${2} # Schlüssellänge: 4096 shift ;; -h) echo " zwingend erforderliche Parameter: -d Domain/FQDN -l Land -c City/Stadt -o Organisation/Mandant -a Abteilung/Marke optionale Parameter: -k Key-Datei der schon existiert -s Staat -m Mail -z Zeitraum der Gültigkeit -b Bit-Länge des Schlüssels Beispiele wild-card-Zertifikat mit neuem Schlüssel: # ${0} -d '*.telco.de' -l Hessen -c Maintal -o Drillisch -a telco Standard-Zertifikat mit vorhandenem Schlüssel: # ${0} -d www.telco.de -s DE -l Hessen -c Maintal -o Drillisch -a telco -k www.telco.de.key -m ssladmin@iq-optimize.de " exit 0 ;; *) if [ "$(echo "${1}"|egrep '^-')" ] ; then echo "Der Parameter '${1}' wird nicht unterstützt!" exit 1 fi shift ;; esac done if [ -z "${STAAT}" ] ; then STAAT="DE" fi if [ -z "${EMAIL}" ] ; then EMAIL="ssladmin@iq-optimize.de" fi ZNAME="$(echo "${DOMAIN}" | tr -s '[*]' 'w')" if [ -z "${DOMAIN}" -o -z "${LAND}" -o -z "${STADT}" -o -z "${ORGANISATION}" -o -z "${ABTEILUNG}" ] ; then echo " Es werden alle Parameter benötigt! => ${0} -h " exit 1 fi if [ -z "${KEY}" ] ; then # neuer Schlüssel echo "openssl req -rand /dev/urandom -sha256 -newkey ec:<(openssl genpkey -genparam -algorithm ec -pkeyopt ec_paramgen_curve:P-${BITLANG}) -nodes -keyout ${ZNAME}.key - keyform PEM -out ${ZNAME}.csr -outform PEM -subj \"/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}\" -days ${ZEITRAUM}" #echo "openssl req -rand /dev/urandom -sha256 -newkey ec:<(openssl ecparam -name secp384r1) -nodes -keyout ${ZNAME}.key -keyform PEM -out ${ZNAME}.csr -outform PEM -sub j \"/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}\" -days ${ZEITRAUM}" openssl req -rand /dev/urandom -sha256 -newkey ec:<(openssl genpkey -genparam -algorithm ec -pkeyopt ec_paramgen_curve:P-${BITLANG}) -nodes -keyout ${ZNAME}.key -keyfor m PEM -out ${ZNAME}.csr -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}" -days ${ZEITRAUM} #openssl req -rand /dev/urandom -sha256 -newkey ec:<(openssl ecparam -name secp384r1) -nodes -keyout ${ZNAME}.key -keyform PEM -out ${ZNAME}.csr -outform PEM -subj "/em ailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${DOMAIN}" -days ${ZEITRAUM} else if [ -r "${KEY}" ] ; then # vorhandener Schlüssel echo "openssl req -new -key ${KEY} -keyform PEM -out ${ZNAME}.csr -outform PEM -subj \"/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION} /OU=${ABTEILUNG}/CN=${DOMAIN}\" -days ${ZEITRAUM}" openssl req -new -key ${KEY} -keyform PEM -out ${ZNAME}.csr -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${A BTEILUNG}/CN=${DOMAIN}" -days ${ZEITRAUM} else echo "die Datei ${KEY} ist nicht lesbar..." exit 1 fi fi if [ -r "${ZNAME}.csr" ] ; then echo "${ZNAME}.csr $(openssl req -text -verify -in ${ZNAME}.csr)" fi if [ -r "${KEY}" ] ; then # nur bei RSA-Schlüsseln haben Schlüssel, Zertifikatsanfrage und Zertifikat den gleichen Modulus echo "${KEY} $(openssl ec -noout -text -in ${KEY} | openssl md5)" fi if [ -r "${ZNAME}.csr" ] ; then echo "${ZNAME}.csr $(openssl req -noout -modulus -in ${ZNAME}.csr | openssl md5)" fi if [ -r "${ZNAME}.crt" ] ; then echo "${ZNAME}.crt $(openssl x509 -noout -modulus -in ${ZNAME}.crt | openssl md5)" fi ==== Zertifikat mit der eigenen CA signieren (RSA) ==== === bin/ca_initialisieren.sh === Dieses Script erstellt eine eigene CA. #!/bin/bash # # Schlüssel mit Zertifikat # für eine CA-Signatur erzeugen # if [ -z "${1}" ] ; then echo "${0} [CA-Name]" exit 1 else ### initialisieren . $(dirname ${0})/cert.cfg rm -fr CA mkdir -p ~/CA/private ~/CA/newcerts && echo '01' > ~/CA/serial && touch ~/CA/index.txt openssl req -x509 -rand /dev/urandom -sha1 -newkey rsa:${BITLANG} -keyout ~/CA/private/ca.key -keyform PEM -out ~/CA/ca.crt -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${1}" -days ${ZEITRAUM} echo -e "[ca]\ndefault_ca=CA_default\n[CA_default]\npolicy=policy_match\nserial=CA/serial\ndatabase=CA/index.txt\n[policy_match]\ncommonName=supplied" > ~/CA/openssl.cnf fi Für eine Testumgebung kann man die Passphrase auch entfernen: # openssl rsa < ~/CA/private/ca.key > ca.key # mv ca.key ~/CA/private/ca.key === bin/ca_cert_neu.sh === Dieses Script generiert einen privaten Schlüssel, ein Zertifikat (öffentlicher Schlüssel) und signiert das Zertifikat mit der eigenen CA. #!/bin/bash # # Schlüssel mit signiertem Zertifikat erzeugen # if [ -z "${1}" ] ; then echo "${0} [FQDN des Zielhost]" echo "${0} www.domain.org" echo "${0} '*.domain.org'" exit 1 else ### generieren ZNAME="$(echo "${1}" | tr -s '[*]' 'i')" . $(dirname ${0})/cert.cfg openssl req -x509 -rand /dev/urandom -sha1 -newkey rsa:${BITLANG} -nodes -keyout ${ZNAME}.key -keyform PEM -out ${ZNAME}.crt -outform PEM -subj "/emailAddress=${EMAIL}/C=${STAAT}/ST=${LAND}/L=${STADT}/O=${ORGANISATION}/OU=${ABTEILUNG}/CN=${1}" -days ${ZEITRAUM} ### signieren openssl ca -config ~/CA/openssl.cnf -batch -md sha1 -selfsign -ss_cert ${ZNAME}.crt -keyfile ~/CA/private/ca.key -cert ~/CA/ca.crt -outdir ~/CA/newcerts/ -days ${ZEITRAUM} echo cp ~/CA/newcerts/$(tail -n1 ~/CA/index.txt | awk '{gsub("="," ");print $3".pem"}') ${ZNAME}.pem rm -f $(tail -n1 ~/CA/index.txt | awk '{gsub("="," ");print $NF".crt"}') openssl x509 -noout -subject -issuer -dates -in ${ZNAME}.pem ls -1 ${ZNAME}.* fi === bin/ssl_check_rsa.sh === #!/bin/bash #------------------------------------------------------------------------------# # # ALT # überprüft ob RSA-SCHLÜSSEL, Zertifikatsanfrage und Zertifikat zusammen gehören # #------------------------------------------------------------------------------# if [ -z "${1}" ] ; then echo "${0} *.simplytel.de.*" exit 1 fi echo for i in ${@} do ENDUNG="$(echo "${i}" | rev | awk -F'.' '{print $1}' | rev)" if [ "${ENDUNG}" == "key" ] ; then MD5PRUEFSUMME_RSA="$(openssl rsa -noout -modulus -in ${i} | openssl md5)" echo "${MD5PRUEFSUMME_RSA} - ${i}" elif [ "${ENDUNG}" == "csr" ] ; then MD5PRUEFSUMME_CSR="$(openssl req -noout -modulus -in ${i} | openssl md5)" echo "${MD5PRUEFSUMME_CSR} - ${i}" elif [ "${ENDUNG}" == "crt" ] ; then MD5PRUEFSUMME_CRT="$(openssl x509 -noout -modulus -in ${i} | openssl md5)" echo "${MD5PRUEFSUMME_CRT} - ${i}" # else # echo "${i} ..." fi done | sort -n echo Zusammengehörigkeit von Schlüssel und Zertifikatsanfrage überprüfen: # /root/bin/ssl_check_rsa.sh *.domain.de.* 0d345e7c7e4db8c05fff48d4c3de17e1 - www.domain.de.crt 0d345e7c7e4db8c05fff48d4c3de17e1 - www.domain.de.csr 0d345e7c7e4db8c05fff48d4c3de17e1 - www.domain.de.key ==== selbst signierte Zertifikate erstellen (EC) ==== [[::EDV:selbst signierte Zertifikate erstellen (EC)]] ===== im Apache HTTPS aktivieren ===== ==== Ubuntu ==== nachlesen wie es geht: # zless /usr/share/doc/apache2.2-common/README.Debian.gz Schlüssel und signiertes Zertifikat an die richtige Stelle legen: # cp www.test.net.pem /etc/ssl/certs/ # cp www.test.net.key /etc/ssl/private/ den gewünschten Schlüssel mit Zertifikat eintragen: # vi /etc/apache2/sites-available/default-ssl ... SSLCertificateFile /etc/ssl/certs/www.test.net.pem SSLCertificateKeyFile /etc/ssl/private/www.test.net.key ... SSL aktivieren: # a2ensite default-ssl # a2enmod ssl # /etc/init.d/apache2 restart ===== openssl -> pkcs12 ===== eine P12-Datei ist praktisch eine verschlüsselte PEM-Datei # openssl pkcs12 -export -out zertifikat.p12 -inkey privater.key -in zertifikat.crt -certfile ca.crt -> [[::EDV:openVPN#Client|Infos aus einem P12-Zertifikat auslesen]]