After the CRYPTO 2004 results were published, NIST announced that they planned to phase out the use of SHA-1 by 2010 in favor of the SHA-2 variants. In 2009 at eurocrypt, a small group of researchers announced a fairly serious attack against the SHA-1 digest algorithm
By default gpg uses CAST5 as a cipher and SHA1 as hash. Below are the steps required to migrate from SHA1 to SHA2 in GPG setup.
In this article I’ve also switched from CAST5 to AES256 cipher, however this is not necessary as there are no known attacks on CAST5-128.
To some users changing the cipher/hash might be inconvenient as the recipient’s version of their GPG might be incompatible with the other cipher/hash.
Some people prefer to generate new keys, however there is a way to keep your key and change just the cipher/hash. This is especially useful when you want to keep your key fingerprint the same and signatures made by your parties. I must also note that most likely your parties have signed your public key using SHA1 hash, so you can ask them to sign it again with a stronger hash.
IMPORTANT: Before you do anything, please make sure you backed-up your imporant keys!
To make GPG keys generation remarkably faster, install “rng-tools” package Debian-based:
apt-get install rng-tools -y
yum install rng-tools -y
The rngd daemon will establish a bridge between the hardware TRNG (True random number generator) and the kernel entropy pool.
Secret key (the one you keep private and never share)
laptop ~ $ gpg -o Alice.sec --export-secret-keys Alice laptop ~ $ gpg -vv --import Alice.sec
IMPORTANT: Do not forget to destroy/shred this temporary copy of your secret key.
laptop ~ $ gpg -o Alice.pub --export Alice laptop ~ $ gpg -vv --import Alice.pub
When viewing your key, you should check your private key output for lines like:
iter+salt S2K, algo: 3, SHA1 protection, hash: 2, salt: c1838489ffcb8b8d
You can observe the algo (cipher) is 3 and the hash (digest) is 2.
Run the following command in order to determine what number corresponds to what cipher/hash:
laptop ~ $ gpg -vv --version gpg (GnuPG) 1.4.16 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Home: ~/.gnupg Supported algorithms: Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA Cipher: IDEA (S1), 3DES (S2), CAST5 (S3), BLOWFISH (S4), AES (S7), AES192 (S8), AES256 (S9), TWOFISH (S10), CAMELLIA128 (S11), CAMELLIA192 (S12), CAMELLIA256 (S13) Hash: MD5 (H1), SHA1 (H2), RIPEMD160 (H3), SHA256 (H8), SHA384 (H9), SHA512 (H10), SHA224 (H11) Compression: Uncompressed (Z0), ZIP (Z1), ZLIB (Z2), BZIP2 (Z3)
So the cipher is (S3) CAST5, and the hash is (H2) SHA1.
Say you want to use AES256/SHA512 as cipher/hash, so you want to run the following command
laptop ~ $ gpg -u Alice --s2k-digest-algo SHA512 --s2k-cipher-algo AES256 --edit-key Alice gpg> passwd gpg> save
This will prompt you to type your current password and the new one. After this is set, write “save” and confirm saving changes and quit.
In order to see if this was really set, you can export your secret key again and view it as described above.
You should see similar line as this:
iter+salt S2K, algo: 9, SHA1 protection, hash: 10, salt: c7c377b33e8546b5
Here you can see algo 9 stands for (S9) AES256 and hash 10 is for (H10) SHA512, just as we were expecting.
You can also use “pgpdump” command over your exported key in order to see more details as such:
... Sym alg - AES with 256-bit key(sym 9) Iterated and salted string-to-key(s2k 3): Hash alg - SHA512(hash 10) Salt - c7 c3 77 b3 3e 85 46 b5 Count - 65536(coded count 96) ...
Note that this modification does not change anything in your public key.
Here we will update cipher/hash preferences of your public key, so that client software of the parties who wish to communicate with you, will prefer them in the order you (your public key) prefer.
NOTE: This is not always valid and can be overriden by the client software settings.
laptop ~ $ gpg -u Alice --edit-key Alice gpg> showpref [ultimate] (1). Alice <alice@wonderland> Cipher: AES256, AES192, AES, CAST5, 3DES Digest: SHA256, SHA1, SHA384, SHA512, SHA224 Compression: ZLIB, BZIP2, ZIP, Uncompressed Features: MDC, Keyserver no-modify gpg> setpref SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed gpg> showpref [ultimate] (1). Alice <alice@wonderland> Cipher: AES256, AES192, AES, CAST5, 3DES Digest: SHA512, SHA384, SHA256, SHA224, SHA1 Compression: ZLIB, BZIP2, ZIP, Uncompressed Features: MDC, Keyserver no-modify gpg> save
Checking the difference, you will see that only the preferred cipher/hash and compression algorithms changed in your public key (pref-sym-algos, pref-hash-algos, pref-zip-algos).
Note that this modification does not change anything in your secret key.
Once you have updated your secret & public key, you might still notice SHA1 is used as hash in your keys:
laptop ~ $ gpg -vv --import Alice.sec 2>&1 |grep digest digest algo 2, begin of digest a5 f0 digest algo 2, begin of digest d2 de laptop ~ $ gpg -vv --import Alice.pub 2>&1 |grep digest digest algo 2, begin of digest 66 f0 digest algo 2, begin of digest d2 de
The reason of that is the self-signature. When you generated your keys (–gen-key), GPG asked for your Real name / Email .. which was used to create a user ID (UID). Then GPG automatically signed this record with your corresponding secret key. It used SHA1 hash, this is why you still see it in your pub/sec keys as shown above.
laptop ~ $ gpg -u Alice --edit-key Alice gpg> list pub 4096R/A28E505A created: 2015-01-04 expires: 2015-01-05 usage: SC trust: ultimate validity: ultimate sub 4096R/394AAE32 created: 2015-01-04 expires: 2015-01-05 usage: E [ultimate] (1). Alice <alice@wonderland> gpg> check uid Alice <alice@wonderland> sig!3 A28E505A 2015-01-04 [self-signature] gpg> quit
To remedy this (SHA1 hash over your UID), you need to delete your UID and create it again (will be signed with SHA-2). But first update your GPG client preferences:
~/.gnupg/gpg.conf personal-cipher-preferences AES256 personal-digest-preferences SHA512 cert-digest-algo SHA512 default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
NOTE: Always keep s2k digest/cipher parameters when you need to create new keys as it involves steps like protecting your new secret keys (or secret subkeys) with your password using the digest(==hash)/cipher you specified.
IMPORTANT: Do not specify the same values when you create your new UID! Otherwise GPG will link your new UID (sha2) to your previous UID, and when you will remove your previous UID (sha1), it will keep no any user ID assigned to your secret key. Because of that GPG won’t display the “uid” when listing the secret keys (gpg -K). I think it can cause other undesirable effects.
I suggest to at least add something to the “Comments” section.
If you really want to keep the same values (Real name, Email, Comments), then you can create a 2nd UID with some different value, remove the 1st UID, and create the 3rd UID with the values you desire. After that you can remove the 2nd UID.
laptop ~ $ gpg -u Alice --s2k-digest-algo SHA512 --s2k-cipher-algo AES256 --edit-key Alice gpg> toggle sec 2048R/EA9C889E created: 2015-01-04 expires: 2015-01-05 ssb 2048R/AD5A81B2 created: 2015-01-04 expires: never (1) Alice <alice@wonderland> gpg> toggle pub 2048R/EA9C889E created: 2015-01-04 expires: 2015-01-05 usage: SC trust: ultimate validity: ultimate sub 2048R/AD5A81B2 created: 2015-01-04 expires: 2015-01-05 usage: E [ultimate] (1). Alice <alice@wonderland>
Create a new temporary UID
gpg> adduid Real name: Alice Email address: alice@wonderland Comment: temporary
Select original UID and delete it (to avoid the linking problem)
gpg> uid 1 gpg> deluid
Create a new UID with the same values as you had in your original UID
gpg> adduid Real name: Alice Email address: alice@wonderland Comment:
Select a temporary UID and delete it
gpg> uid 1 ggp> deluid gpg> save
This way you will have Real name, Email and Comments unchanged, and the UID will be signed with SHA1 hash.
GPG also created the subkey (sub) and the secret subkey (ssb) which are used for encryption/decryption And the subkey was signed by your secret key, again with the SHA1 digest. You can either delete your subkey or revoke the signature of your subkey. The latter will stop the parties from using that subkey but will still let you decrypt the data which was encrypted in past with its corresponding secret subkey (ssb). If you don’t have anything that you still need to decrypt with your old subkey, you can remove it completely:
(Option A) To remove your sub/ssb keys:
gpg> key 1 gpg> delkey
(Option B) To revoke your sub/ssb keys:
gpg> key 1 gpg> revkey
After that you need to create new sub/ssb keypair:
Choose RSA or Elgamal and (encrypt only).
Now use methods above to export and view the properties of your keys to ensure that cipher/hash used as you set.
For obvious reasons, don’t forget to shred the secret key copy we did for tests
shred -uvz Alice.sec ; rm Alice.pub