**Hier ist noch nicht alles getestet, bitte nur mit Vorsicht benutzen**
====== Problem ======
Bei 'normalen' (as in ohne Master- und Subkey) GPG-Keys hat man den Nachteil dass, wenn man den privaten Schlüssel verliert man zwar den Key widerrufen (revoke) kann damit aber auch alle Signaturen verliert und damit auch seine "Identität" im web of trust.
Mit Subkeys kann zumindest der Schaden für die eigene "Identität" begrenzt werden.
====== Subkeys ======
Das Konzept ist folgendes:
Es wird ein reguläres GPG-Schlüsselpaar generiert welches aus einem Signingkey (die eigentliche Identität im web of trust) besteht. Es werden weitere Subkeys zum verschlüsseln und signieren generiert. Entfernt man den Masterkey erhält man einen Keyring für den alltäglichen Gebrauch. Gehen diese verloren, kann man mit dem Backup des Masterkeys die kompromitierten keys widerrufen und neue Subkeys genierieren, die Identität bleibt dabei immer an den Masterkey gebunden.
====== How To Subkeys ======
===== Backup anlegen =====
Sollten schon GPG-Keys auf dem System existieren ist es eine gute Idee ein Backup anzulegen
umask 077; tar -cf $HOME/gnupg-backup.tar -C $HOME .gnupg
===== gpg.conf =====
Eine Basisinstallation von GnuPG nimmt sehr große Rücksicht auf die Kompatibiliätät mit alten Versionen. Ähnlich wie die "Cipher Lists" von TLS-Servern kann auch diese Konfiguration gehärtet werden.
# gpg.conf auf Basis von
# https://github.com/ioerror/duraconf/blob/adb7536149263a02f7017b284e5cca07cc4331c1/configs/gnupg/gpg.conf
#
# This is an implementation of the Riseup OpenPGP Best Practices
# https://help.riseup.net/en/security/message-security/openpgp/best-practices
#
#-----------------------------
# default key
#-----------------------------
# The default key to sign with. If this option is not used, the default key is
# the first key found in the secret keyring
#default-key 0xD8692123C4065DEA5E0F3AB5249B39D24F25E3B6
#-----------------------------
# behavior
#-----------------------------
# Disable output of copyright & version information
no-greeting
# Disable inclusion of the version string in ASCII armored output
no-emit-version
# Disable comment string in clear text signatures and ASCII armored messages
no-comments
# Display long key IDs
keyid-format 0xlong
# List all keys (or the specified ones) along with their fingerprints
with-fingerprint
# Display the calculated validity of user IDs during key listings
list-options show-uid-validity
verify-options show-uid-validity
# Try to use the GnuPG-Agent. With this option, GnuPG first tries to connect to
# the agent before it asks for a passphrase.
use-agent
# Charset used for output
display-charset utf-8
# Charset used to interpret input
utf8-strings
#-----------------------------
# keyserver
#-----------------------------
# This is the server that --recv-keys, --send-keys, and --search-keys will
# communicate with to receive keys from, send keys to, and search for keys on
keyserver hkp://pool.sks-keyservers.net
# HKP reveals the requested identities during the network transport.
# Use HKPS *instead* to protect this information.
# To use a HKPS (secure HKP) the correct CA certificate must be downloaded.
# wget -O/path/to/hkps.pool.sks-keyservers.net.pem https://sks-keyservers.net/sks-keyservers.netCA.pem
# Please read: https://sks-keyservers.net/overview-of-pools.php#pool_hkps
#keyserver hkps://hkps.pool.sks-keyservers.net ca-cert-file=/path/to/hkps.pool.sks-keyservers.net.pem
# Provide a certificate store to override the system default
# Get this from https://sks-keyservers.net/sks-keyservers.netCA.pem
# keyserver-options ca-cert-file=/usr/local/etc/ssl/certs/hkps.pool.sks-keyservers.net.pem
# Set the proxy to use for HTTP and HKP keyservers - default to the standard
# local Tor socks proxy
# It is encouraged to use Tor for improved anonymity. Preferrably use either a
# dedicated SOCKSPort for GnuPG and/or enable IsolateDestPort and
# IsolateDestAddr
#keyserver-options http-proxy=socks5-hostname://127.0.0.1:9050
# Don't leak DNS, see https://trac.torproject.org/projects/tor/ticket/2846
#keyserver-options no-try-dns-srv
# When using --refresh-keys, if the key in question has a preferred keyserver
# URL, then disable use of that preferred keyserver to refresh the key from
keyserver-options no-honor-keyserver-url
# When searching for a key with --search-keys, include keys that are marked on
# the keyserver as revoked
keyserver-options include-revoked
#-----------------------------
# algorithm and ciphers
#-----------------------------
# list of personal digest preferences. When multiple digests are supported by
# all recipients, choose the strongest one
personal-cipher-preferences AES256 AES192 AES CAST5
# list of personal digest preferences. When multiple ciphers are supported by
# all recipients, choose the strongest one
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
# message digest algorithm used when signing a key
cert-digest-algo SHA512
# This preference list is used for new keys and becomes the default for
# "setpref" in the edit menu
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
==== Hinweise und Erläuterungen ====
* zu //display-charset utf-8// und //utf8-strings//: Ein funktionierendes UTF-8 Setup der Benutzerumgebung wird vorausgesetzt!
* zu //keyid-format 0xlong//: [[https://www.heise.de/security/meldung/Boese-Schluessel-werden-zum-Problem-fuer-GnuPG-2473281.html|heise: Böse Schlüssel werden zum Problem für GnuPG]], [[https://www.heise.de/security/meldung/Haufenweise-Fake-PGP-Schluessel-im-Umlauf-3297175.html|Haufenweise Fake-PGP-Schlüssel im Umlauf]]
* zu //no-comments// (ebenfalls zur Beachtung beim erstellen neuer Identitäten): [[https://debian-administration.org/users/dkg/weblog/97|OpenPGP User ID Comments considered harmful]]
* zu //keyserver-options no-honor-keyserver-url//: Diese Option deaktiviert die Berücksichtigung von dritten, durch Erstellern importierter, öffentlicher Schlüssel hinterlegter Keyserver. Damit wird möglicherweise die Aktualisierung von Schlüsseln aus geschlossenen Benutzergruppen mit eigenem Keyserver erschwert.
* zu //#keyserver-options no-try-dns-srv//: GPG zieht zur Abfrage von Schlüsselservern mitunter auch DNS SRV Einträge heran (und erschwert damit den spurenarmen Einsatz in Verbindung mit TOR). Nicht alle GPG-Versionen unterstützen diese Option, deshalb ist sie standardmäßig nicht aktiv.
* zu //personal-cipher-preferences// und //personal-digest-preferences//: ausgehende Nachrichten werden bevorzugt (soweit vom Empfänger unterstützt) mit diesen Verfahren erstellt.
* zu //cert-digest-algo SHA512//: Schlüsselsignaturen werden damit mit SHA512 (statt üblicherweise SHA1) durchgeführt
* zu //default-preference-list//: **neue** Identitäten erhalten diese bevorzugten Verfahren für den eigenen Nachrichtenempfang
* Sämtliche, in den vorausgehend erläuterten Verfahren müssen von der eigenen gpg-Version unterstützt sein (Verfikation mit //gpg --version//)
* Die in der obigen Konfiguration gemachten Anpassungen (als "patch", ">" markiert ergänzte Passagen, "<" dagegen entfernte) gegenüber [[https://github.com/ioerror/duraconf/blob/adb7536149263a02f7017b284e5cca07cc4331c1/configs/gnupg/gpg.conf|gpg.conf]] gemäß der [[https://help.riseup.net/en/security/message-security/openpgp/best-practices|Riseup OpenPGP Best Practices]]:
0a1,3
> # gpg.conf auf Basis von
> # https://github.com/ioerror/duraconf/blob/adb7536149263a02f7017b284e5cca07cc4331c1/configs/gnupg/gpg.conf
>
20a24,26
> # Disable output of copyright & version information
> no-greeting
>
40a47,52
> # Charset used for output
> display-charset utf-8
>
> # Charset used to interpret input
> utf8-strings
>
48c60,67
< keyserver hkps://hkps.pool.sks-keyservers.net
---
> keyserver hkp://pool.sks-keyservers.net
>
> # HKP reveals the requested identities during the network transport.
> # Use HKPS *instead* to protect this information.
> # To use a HKPS (secure HKP) the correct CA certificate must be downloaded.
> # wget -O/path/to/hkps.pool.sks-keyservers.net.pem https://sks-keyservers.net/sks-keyservers.netCA.pem
> # Please read: https://sks-keyservers.net/overview-of-pools.php#pool_hkps
> #keyserver hkps://hkps.pool.sks-keyservers.net ca-cert-file=/path/to/hkps.pool.sks-keyservers.net.pem
52c71
< keyserver-options ca-cert-file=/usr/local/etc/ssl/certs/hkps.pool.sks-keyservers.net.pem
---
> # keyserver-options ca-cert-file=/usr/local/etc/ssl/certs/hkps.pool.sks-keyservers.net.pem
62c81
< keyserver-options no-try-dns-srv
---
> #keyserver-options no-try-dns-srv
===== Masterkey generieren =====
gpg --gen-key
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection?
**4**
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
**4096**
Requested keysize is 4096 bits
Please specify how long the key should be valid.
0 = key does not expire
= key expires in n days
w = key expires in n weeks
m = key expires in n months
y = key expires in n years
Key is valid for? (0)
**0**
Key does not expire at all
Is this correct? (y/N)
**y**
[...]
**Enter Credentials**
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?
**O**
===== Signin Subkey generieren =====
Key id raussuchen:
gpg --list-keys $NAME
Masterkey editieren:
gpg --edit-key $MASTERKEYID
gpg> addkey
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
Your selection?
**4**
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
**4096**
Requested keysize is 4096 bits
Please specify how long the key should be valid.
0 = key does not expire
= key expires in n days
w = key expires in n weeks
m = key expires in n months
y = key expires in n years
Key is valid for? (0)
**2y**
===== Encryption Subkey generieren =====
Wie beim Signing Subkey nur diesmal als Keytype **6** auswählen
===== Revocation Certificate generieren =====
gpg --output $REVOKECERT --gen-revoke $MASTERKEYID
Dieses revocation certificate wird nur benutzt um den Masterkey zu widerrufen, falls dieser verloren geht. Subkeys werden mit dem Masterkey widerrufen, nicht mit diesem Zertifikat!
===== Masterkey und Subkey exportieren =====
gpg --armor --export-secret-keys $MASTERKEYID > $MASTERKEYID_secret.asc
gpg --armor --export-secret-subkeys $MASTERKEYID > $MASTERKEYID_secret_subkeys.asc
Diese beiden Dateien und das revocation certificate für den Masterkey müssen auf einen (verschlüsselten) USB Stick o.ä. gespeichert und sicher aufbewahrt werden!
Wird kein Livesystem zum generieren der Keys verwendet sollten die Dateien danach zerstört werden
shred -vfzu -n 10 $MASTERKEYID_secret.asc $MASTERKEYID_secret_subkeys.asc $REVOKECERT
===== Subkeys exportieren =====
gpg --output $SUBFILENAME --export-secret-subkeys $MASTERKEYID
===== Masterkey löschen =====
gpg --delete-secret-keys $MASTERKEYID
===== Subkeys wieder importieren =====
gpg --import $SUBFILENAME
===== Passwort für den Subkey ändern =====
gpg --edit-key $MASTERKEYID
gpg> passwd
[...]
===== Überprüfen des Schlüsselbundes =====
gpg -K
/home/gpg/.gnupg/secring.gpg
----------------------------
sec# 4096R/0xFFFFFFFFFFFFFFFF 2016-05-17
uid Foo Bar
ssb 4096R/0xEEEEEEEEEEEEEEEE 2016-05-17
ssb 4096R/0xDDDDDDDDDDDDDDDD 2016-05-17
gpg -k
/home/gpg/.gnupg/pubring.gpg
----------------------------
pub 4096R/0xFFFFFFFFFFFFFFFF 2016-05-17
uid [ultimate] Foo Bar
sub 4096R/0xEEEEEEEEEEEEEEEE 2016-05-17 [expires: 2018-05-17]
sub 4096R/0xDDDDDDDDDDDDDDDD 2016-05-17 [expires: 2018-05-17]
In diesem Beispiel gibt es einen geheimen 4096-bit langen, RSA-Masterkey (sec#) mit der ID 0xFFFFFFFFFFFFFFFF. Die # zeigt dass der eigenliche Masterkey nicht(!) im Schlüsselbund vorhanden ist und nur Metainformationen angezeigt werden. Wäre der Masterkey vorhanden würde die # fehlen. Die user-id (uid) und die dazugehörige Emailadresse des Masterkeys sind Metainformationen. Der Master key hat zwei geheime sub keys (ssb). Jeder Subkey hat eine eigene ID.
====== How To Keysigning ======
===== Masterkey importieren =====
gpg --no-default-keyring --keyring ./tmp-public-kr.gpg --secret-keyring ./tmp-private-kr.gpg --trustdb-name ./tmp-trustdb.gpg --import ../$MASTERKEYID_secret.asc
===== Key importieren =====
gpg --no-default-keyring --keyring ./tmp-public-kr.gpg --secret-keyring ./tmp-private-kr.gpg --trustdb-name ./tmp-trustdb.gpg \
--keyserver x-hkp://$KEYSERVER --recv-keys $FOREIGNKEYID
===== Import überprüfen ======
gpg --no-default-keyring --keyring ./tmp-public-kr.gpg --secret-keyring ./tmp-private-kr.gpg --trustdb-name ./tmp-trustdb.gpg \
--list-keys $FOREIGNKEYID
===== Key signieren =====
gpg --no-default-keyring --keyring ./tmp-public-kr.gpg --secret-keyring ./tmp-private-kr.gpg --trustdb-name ./tmp-trustdb.gpg
--sign-key --ask-cert-level $FOREIGNKEY
===== Key an Keyserver senden =====
gpg --no-default-keyring --keyring ./tmp-public-kr.gpg --secret-keyring ./tmp-private-kr.gpg --trustdb-name ./tmp-trustdb.gpg
--keyserver keys.gnupg.net --send-key $FOREIGNKEYID
====== How To Subkey widerrufen (revoke) ======
===== Masterkey importieren =====
gpg --no-default-keyring --keyring /tmp-public-kr.gpg --secret-keyring ./tmp-private-kr.gpg --trustdb-name ./tmp-trustdb.gpg --import path/to/$MASTERKEYID_secret.asc
===== Revokecertificate generieren =====
gpg --no-default-keyring --keyring ./tmp-public-kr.gpg --secret-keyring ./tmp-private-kr.gpg --trustdb-name ./tmp-trustdb.gpg
--expert --edit-key $MASTERKEYID
gpg> list
gpg> key 1
gpg> key 2
gpg> revoke
===== Key an Keyserver senden =====
gpg --no-default-keyring --keyring ./tmp-public-kr.gpg --secret-keyring ./tmp-private-kr.gpg --trustdb-name ./tmp-trustdb.gpg --send-key --keyserver $KEYSERVER $MASTERKEYID
====== optional: Raspberry Pi Hardware Zufallszahlengenerator ======
http://scruss.com/blog/2013/06/07/well-that-was-unexpected-the-raspberry-pis-hardware-random-number-generator/
http://pastehtml.com/view/crkxyohmp.rtxt
http://lxr.free-electrons.com/source/drivers/char/hw_random/bcm2835-rng.c?v=4.4#L64
sudo tee -a /boot/config.txt <
====== optional: Javacard / OpenPGPCard unter Debian Jessie erstellen ======
Java-Compiler, ant, git, Smartcard-Daemon für GnuPG 2 und Chipkartentreiber installieren
# Debian Jessie
sudo apt-get -y install git openjdk-8-jdk ant libccid libifd-cyberjack6 scdaemon
OpenPGPCard Cardlet auschecken, kompilieren & auf JavaCard installieren
git clone https://github.com/jderuiter/javacard-openpgpcard.git
cd javacard-openpgpcard
ant
# Smartcard einlegen / mit USB verbinden
ant install
cd ..
Toolkit für GlobalPlatform installieren um Karte zu "versiegeln"
git clone https://github.com/martinpaljak/GlobalPlatformPro.git
cd GlobalPlatformPro
ant
java -jar gp.jar -lock $(dd bs=16 count=1 status=none if=/dev/urandom | hexdump -ve '/1 "%02X"')
# DES3 Key notieren!!!
# Karte wieder entsperren mit (0123456789ABCDEF0123456789ABCDEF mit notiertem Key ersetzen):
# java -jar gp.jar -key 0123456789ABCDEF0123456789ABCDEF -lock
cd ..