How to get rid of or update my "Primary Key Binding Signature (0x19)"?

I am trying to clean all my existing keys and identities from signatures based on SHA1 and replace them with signatures based on SHA512, without having to create new (sub) keys, as they are still in use somewhere else.

Found this helpful article (in German) which helped me a lot, I was able to force gpg to update the self-signatures of my identity and my subkeys based on SHA512, all fine.

But: There is one stubborn “embedded signature” of type “Primary Key Binding Signature(0x19)” inside one of my (properly updated) “Subkey Binding Signature(0x18)” which refuses to be updated. Whatever I tried for hours and hours, after googling half of the internet, it stays on “Hash alg - SHA1(hash 2)”, and its creation timestamp does not move.

Here is an anonymized, annotated gpgdump of my problematic key:

bernd@arch:~ (0) $ gpg --export ************ | pgpdump 
gpg: Note: signatures using the SHA1 algorithm are rejected
Old: Public Key Packet(tag 6)(525 bytes)
        Ver 4 - new
        Public key creation time - Sun Sep 25 11:01:21 CEST 2016
        Pub alg - RSA Encrypt or Sign(pub 1)
        RSA n(4096 bits) - ...
        RSA e(17 bits) - ...
Old: User ID Packet(tag 13)(51 bytes)
        User ID - Bernd <my_email@some_domain.com>
Old: Signature Packet(tag 2)(595 bytes)
        Ver 4 - new
        Sig type - Positive certification of a User ID and Public Key packet(0x13).
        Pub alg - RSA Encrypt or Sign(pub 1)
        Hash alg - SHA512(hash 10)
        Hashed Sub: issuer fingerprint(sub 33)(21 bytes)
         v4 -   Fingerprint - a1 5d ** ** ** ** ** ** ** **
        Hashed Sub: signature creation time(sub 2)(4 bytes)
                Time - Sat Apr 20 15:32:57 CEST 2024
        Hashed Sub: key flags(sub 27)(1 bytes)
                Flag - This key may be used to certify other keys
        Hashed Sub: key expiration time(sub 9)(4 bytes)
                Time - Mon Apr 20 12:10:08 CEST 2026
        Hashed Sub: preferred symmetric algorithms(sub 11)(3 bytes)
                Sym alg - AES with 256-bit key(sym 9)
                Sym alg - Twofish with 256-bit key(sym 10)
                Sym alg - Blowfish(sym 4)
        Hashed Sub: preferred hash algorithms(sub 21)(4 bytes)
                Hash alg - SHA512(hash 10)
                Hash alg - SHA384(hash 9)
                Hash alg - SHA256(hash 8)
                Hash alg - RIPEMD160(hash 3)
        Hashed Sub: preferred compression algorithms(sub 22)(4 bytes)
                Comp alg - ZLIB <RFC1950>(comp 2)
                Comp alg - BZip2(comp 3)
                Comp alg - ZIP <RFC1951>(comp 1)
                Comp alg - Uncompressed(comp 0)
        Hashed Sub: features(sub 30)(1 bytes)
                Flag - Modification detection (packets 18 and 19)
        Hashed Sub: key server preferences(sub 23)(1 bytes)
                Flag - No-modify
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0x****************
        Hash left 2 bytes - 3e 68 
        RSA m^d mod n(4094 bits) - ...
                -> PKCS-1
Old: Public Subkey Packet(tag 14)(525 bytes)
        Ver 4 - new
        Public key creation time - Sun Sep 25 11:01:21 CEST 2016
        Pub alg - RSA Encrypt or Sign(pub 1)
        RSA n(4096 bits) - ...
        RSA e(17 bits) - ...
Old: Signature Packet(tag 2)(572 bytes)
        Ver 4 - new
        Sig type - Subkey Binding Signature(0x18).
        Pub alg - RSA Encrypt or Sign(pub 1)
        Hash alg - SHA512(hash 10)
        Hashed Sub: key flags(sub 27)(1 bytes)
                Flag - This key may be used to encrypt communications
                Flag - This key may be used to encrypt storage
        Hashed Sub: issuer fingerprint(sub 33)(21 bytes)
         v4 -   Fingerprint - a1 5d ** ** ** ** ** **
        Hashed Sub: signature creation time(sub 2)(4 bytes)
                Time - Sat Apr 20 15:39:53 CEST 2024
        Hashed Sub: key expiration time(sub 9)(4 bytes)
                Time - Mon Apr 20 15:39:53 CEST 2026
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0x****************
        Hash left 2 bytes - 6e 76 
        RSA m^d mod n(4095 bits) - ...
                -> PKCS-1
Old: Public Subkey Packet(tag 14)(525 bytes)
        Ver 4 - new
        Public key creation time - Sun Sep 25 17:29:13 CEST 2016
        Pub alg - RSA Encrypt or Sign(pub 1)
        RSA n(4096 bits) - ...
        RSA e(17 bits) - ...
Old: Signature Packet(tag 2)(1116 bytes)
        Ver 4 - new
        Sig type - Subkey Binding Signature(0x18).
        Pub alg - RSA Encrypt or Sign(pub 1)
a) -->  Hash alg - SHA512(hash 10)
        Hashed Sub: key flags(sub 27)(2 bytes)
                Flag - This key may be used to encrypt communications
                Flag - This key may be used to encrypt storage
        Hashed Sub: issuer fingerprint(sub 33)(21 bytes)
         v4 -   Fingerprint - a1 5d ** ** ** ** ** **
        Hashed Sub: signature creation time(sub 2)(4 bytes)
b) -->          Time - Sat Apr 20 15:52:17 CEST 2024
        Hashed Sub: key expiration time(sub 9)(4 bytes)
                Time - Sun Apr 21 15:52:17 CEST 2024
        Sub: embedded signature(sub 32)(540 bytes)
        Ver 4 - new
        Sig type - Primary Key Binding Signature(0x19).
        Pub alg - RSA Encrypt or Sign(pub 1)
c) -->  Hash alg - SHA1(hash 2)
        Hashed Sub: signature creation time(sub 2)(4 bytes)
d) -->          Time - Sun Sep 25 17:29:13 CEST 2016
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0x****************
        Hash left 2 bytes - 24 78 
        RSA m^d mod n(4095 bits) - ...
                -> PKCS-1
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0x****************
        Hash left 2 bytes - 7f 67 
        RSA m^d mod n(4094 bits) - ...
                -> PKCS-1

a) “Parent” subkey binding signature 0x18 was updated properly to SHA512
b) … just now a few minutes ago
c) But the embedded primary key binding signature 0x19 is still on SHA1,
d) … and it was obviously not updated, it is still the same one from years ago.

How can I get rid of that embedded primary key binding signature (in order to force gpg to update it), or update it right away?

Hi Bernd,

while taking note what is written in the Heise Artikel you have linked: “In diesem Kontext ist die Verwendung von SHA1 kein Sicherheitsproblem.” (Roughly: The Usage of SHA1 in this context is not a security issue.)…

… what you try to do seems to be a rare operation. As far as I understand most people would and should do a new keypair in the situation if they are worried about the looks of a secure usage of SHA1. A new keypair would defend against some attacks which are more realistic (like someone getting access to your keypair and passphrase on one if your machines where it is in use).

As next step, you can ask on the gnupg-users mailinglist (Gnupg-users Info Page) and see if someone else has tried this in the past or has other idea.

Best Regards,
Bernhard

Hi,

You can try to use gpg --key-edit and then use the “backsign” command. I am not sure whether this still works- it was introduced once when we added those backsigns and allowed to add backsign to existing key. All in all those backsigns mitigate a not too serious attack and using SHA-1 is definitely not a problem. Replacing SHA-1 is in many cases (but not all) just like fast fashion.

For details on backsigns see
https://gnupg.org/faq/subkey-cross-certify.html

Hello,

Thank you for your reply. Yes, I am aware that it would be a better idea to just create a new sub key, which would be more secure anyway, and which would be hashed with a newer algo (SHA512); tried that, too, and it worked. I will probably end up doing that.

The reason for me to try to “re-cross-back-sign” my old key is a) because it is still in use somewhere, and I wanted to keep it while making it perfect with SHA512 everywhere.

And, more important, b) I found it a nice challenge to try to achieve what I wanted to achieve, and I learned a lot about GnuPG while trying all the things :slight_smile: And after some more trying, I achieved what I wanted, see my other reply below.

Cheers
Bernd

Hi,

I tried that, but gpg says “signing subkey is already cross-certified”, and changes nothing. So with this, I cannot make it re-write that 0x19 key binding signature c) and d) in my original post:

gpg> list

sec  rsa4096/****************
     created: 2016-09-25  expires: 2026-04-27  usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa4096/****************
     created: 2016-09-25  expires: 2026-04-27  usage: E   
ssb  rsa4096/****************
     created: 2016-09-25  expires: 2026-04-27  usage: S   
[ultimate] (1). Bernd <email@example.com>

gpg> cross-certify
subkey **************** does not sign and so does not need to be cross-certified
signing subkey **************** is already cross-certified

gpg> backsign
subkey **************** does not sign and so does not need to be cross-certified
signing subkey **************** is already cross-certified

However, after quite some more googling, I found these instructions on how to achieve it. Really the opposite of straight-forward and easy, but I achieved exactly what I wanted, 0x18 self-signature and 0x19 primary key binding signature were both re-written with hash algo 10 = SHA512.

But: It brings me to another question: My new key has an additional flag “R” which I have never seen before, see below. It seems to be an “ADSK Additional Decryption Subkey”, but I never wanted one, or to be more precise, I did not want to transform my old pure “S” key into an “SR” key. I cannot get rid of that “R”, not even with “change-usage” command. And I do not understand what the exact restrictions are due to that “R”. The –with-colon format specification says under

“Field 12 - Key capabilities”
[…]
“- r :: Restricted encryption (subkey only use)”

What does it mean? What is the restriction when signing something with this key? Could not find a satisfying answer in the net.

sec  rsa4096/****************
     created: 2016-09-25  expires: 2026-04-20  usage: C   
     trust: ultimate      validity: ultimate
ssb  rsa4096/****************
     created: 2016-09-25  expires: 2026-04-20  usage: E   
ssb  rsa4096/****************
     created: 2016-09-25  expires: 2026-04-20  usage: SR  
[ultimate] (1). Bernd <mail@examplecom>

But: It brings me to another question: My new key has an
additional flag “R” which I have never seen before, see below. It
seems to be an “ADSK Additional Decryption Subkey”, but I never wanted

You are using some older or dev versions. It was fixed in 2.4.4; see
https://dev.gnupg.org/rG1a2c8267f54ba0a55fa2f87fdc19068b0088510f

What does it mean? What is the restriction when signing something with
this key? Could not find a satisfying answer in the net.

See ADSK: The Additional Decryption Subkey

Shalom-Salam,

Werner

You are using some older or dev versions. It was fixed in 2.4.4; see
rG1a2c8267f54b

No, I was using version 2.4.5, but still got that “R” issue. It seems like the fix does not work when re-adding an existing key using a keygrip. I can reproduce it with this script, with which I am getting the output below:

#!/bin/bash

export GNUPGHOME=.gnupg_bup

# Print gpg version
gpg --version

# Ensure keystore is "clean", i.e. does not contain keys from earlier trials
gpg --delete-secret-and-public-keys test-3

# Create new key
gpg --gen-key --batch <<EOF
%no-protection
Key-Type: EDDSA
Key-Curve: ed448
Key-Usage: cert
Name-Real: Meh Muh
Name-Email: test-3@example.org
Expire-Date: 2025-01-01
subkey-type: ecdh
Subkey-curve: cv448
EOF

# Add rsa4096 subkey for signing
gpg --batch --command-fd 3 --pinentry-mode loopback --edit-key test-3 3<< EOF
addkey
4
4096
2y

save
EOF

# Capture keygrip of that subkey
KEYGRIP=$(gpg --with-keygrip --with-colons --list-key test-3 | tail -n 1 | grep -o -E '[0-9A-F]+')
echo Keygrip: $KEYGRIP

# Delete subkey
gpg --batch --command-fd 3 --edit-key test-3 3<< EOF
key 2
delkey
y
save
EOF

# Add subkey again using keygrip from before
gpg --expert --batch --command-fd 3 --pinentry-mode loopback --edit-key test-3 3<< EOF
addkey
13
$KEYGRIP
e
q
2y
save
EOF

# In last output, you can see that this time, signing subkey was created with "SR" usage!

Produces:

bernd@arch:~ (0) $ ./gpg_test.sh 
gpg (GnuPG) 2.4.5
libgcrypt 1.10.3-unknown
Copyright (C) 2024 g10 Code GmbH
License GNU GPL-3.0-or-later <https://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: /home/bernd/.gnupg_bup
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128,
        CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
gpg (GnuPG) 2.4.5; Copyright (C) 2024 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


sec  ed448/CFC88C467327F6B5 2024-05-01 Meh Muh <test-3@example.org>

Delete this key from the keyring? (y/N) y
This is a secret key! - really delete? (y/N) y

pub  ed448/CFC88C467327F6B5 2024-05-01 Meh Muh <test-3@example.org>

Delete this key from the keyring? (y/N) y
gpg: revocation certificate stored as '/home/bernd/.gnupg_bup/openpgp-revocs.d/39DDC1FADE199B6727D7A6C969AC8EDE621CF4329537517655D923515BB7D3D4.rev'
Secret key is available.

gpg: checking the trustdb
gpg: public key of ultimately trusted key 87913F66B9BFE128 not found
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: Note: signatures using the SHA1 algorithm are rejected
gpg: depth: 0  valid:  10  signed:   1  trust: 0-, 0q, 0n, 0m, 0f, 10u
gpg: depth: 1  valid:   1  signed:   0  trust: 1-, 0q, 0n, 0m, 0f, 0u
gpg: next trustdb check due at 2025-01-01
sec  ed448/39DDC1FADE199B67
     created: 2024-05-01  expires: 2025-01-01  usage: C   
     trust: ultimate      validity: ultimate
ssb  cv448/05EE528612DAEC84
     created: 2024-05-01  expires: 2025-01-01  usage: E   
[ultimate] (1). Meh Muh <test-3@example.org>

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
  (10) ECC (sign only)
  (12) ECC (encrypt only)
  (14) Existing key from card
RSA keys may be between 1024 and 4096 bits long.
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key expires at Fri 01 May 2026 01:19:45 PM CEST

sec  ed448/39DDC1FADE199B67
     created: 2024-05-01  expires: 2025-01-01  usage: C   
     trust: ultimate      validity: ultimate
ssb  cv448/05EE528612DAEC84
     created: 2024-05-01  expires: 2025-01-01  usage: E   
ssb  rsa4096/E8CA45739699A50A
     created: 2024-05-01  expires: 2026-05-01  usage: S   
[ultimate] (1). Meh Muh <test-3@example.org>

Keygrip: 54A6156ED35FED648AAE4B59B47519BD40FFE554
Secret key is available.

sec  ed448/39DDC1FADE199B67
     created: 2024-05-01  expires: 2025-01-01  usage: C   
     trust: ultimate      validity: ultimate
ssb  cv448/05EE528612DAEC84
     created: 2024-05-01  expires: 2025-01-01  usage: E   
ssb  rsa4096/E8CA45739699A50A
     created: 2024-05-01  expires: 2026-05-01  usage: S   
[ultimate] (1). Meh Muh <test-3@example.org>


sec  ed448/39DDC1FADE199B67
     created: 2024-05-01  expires: 2025-01-01  usage: C   
     trust: ultimate      validity: ultimate
ssb  cv448/05EE528612DAEC84
     created: 2024-05-01  expires: 2025-01-01  usage: E   
ssb* rsa4096/E8CA45739699A50A
     created: 2024-05-01  expires: 2026-05-01  usage: S   
[ultimate] (1). Meh Muh <test-3@example.org>


sec  ed448/39DDC1FADE199B67
     created: 2024-05-01  expires: 2025-01-01  usage: C   
     trust: ultimate      validity: ultimate
ssb  cv448/05EE528612DAEC84
     created: 2024-05-01  expires: 2025-01-01  usage: E   
[ultimate] (1). Meh Muh <test-3@example.org>

Secret key is available.

sec  ed448/39DDC1FADE199B67
     created: 2024-05-01  expires: 2025-01-01  usage: C   
     trust: ultimate      validity: ultimate
ssb  cv448/05EE528612DAEC84
     created: 2024-05-01  expires: 2025-01-01  usage: E   
[ultimate] (1). Meh Muh <test-3@example.org>

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
  (14) Existing key from card

Possible actions for this RSA key: Sign Encrypt Authenticate 
Current allowed actions: Sign Encrypt 

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished


Possible actions for this RSA key: Sign Encrypt Authenticate 
Current allowed actions: Sign 

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key expires at Fri 01 May 2026 01:19:46 PM CEST

sec  ed448/39DDC1FADE199B67
     created: 2024-05-01  expires: 2025-01-01  usage: C   
     trust: ultimate      validity: ultimate
ssb  cv448/05EE528612DAEC84
     created: 2024-05-01  expires: 2025-01-01  usage: E   
ssb  rsa4096/472FF859796E9F25
     created: 2024-05-01  expires: 2026-05-01  usage: SR  
[ultimate] (1). Meh Muh <test-3@example.org>