Renewing gpg key "secret key parts are not available" - gnupg

Running gpg 1.4 and last year I setup a key to use with aptly.
The key has now expired and I can't seem to renew. Tried all sorts of things and not getting anywhere, partly because I set it up a year ago.
gpg --edit-key C8FF59B8
Secret key is available.
pub 4096R/C8FF59B8 created: 2017-12-03 expires: never usage: SC
trust: ultimate validity: ultimate
sub 4096R/30F7AC50 created: 2017-12-03 expires: never usage: E
sub 4096R/8C015D46 created: 2017-12-03 expired: 2018-12-03 usage: S
[ultimate] (1). Name <email>
So I can see my key 8C015D46 expired today.
Then I tried
key 2
expire
and chose 1y. I get:
gpg: secret key parts are not available
gpg: make_keysig_packet failed: general error
From what I've read its something to do with master key being offline. I've got the private key saved offline, how do I go about renewing the key?
gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub 4096R/C8FF59B8 2017-12-03
uid Name <email>
sub 4096R/30F7AC50 2017-12-03
List of secret keys
gpg --list-secret-key 8C015D46
sec# 4096R/C8FF59B8 2017-12-03
uid Name <email>
ssb 4096R/30F7AC50 2017-12-03
ssb 4096R/8C015D46 2017-12-03 [expires: 2018-12-03]

Related

Import secret keys into gpg is imported but not really?

I would like to import my secret key from another laptop so I did :
$ gpg2 --allow-secret-key-import --import /mnt/very-secret/private/keys/my-precious.asc
gpg: key 51D5DF*********: "John Doe <john.doe#acme.com>" not changed
gpg: key 51D5DF*********: secret key imported
gpg: Total number processed: 1
gpg: unchanged: 1
gpg: secret keys read: 1
gpg: secret keys unchanged: 1
But later on I did :
$ gpg2 --list-secret-keys | grep 51D5DF
And I don't see my secret key. I don't understand why it isn't visible with the --list-secret-keys option.

Gnupg - Decrypt file

I'm trying to decrypt a file but I get the following:
gpg <file name>
gpg: encrypted with 2048-bit RSA key, ID 4A83B612, created 2018-02-19
"user <email>"
gpg: decryption failed: secret key not available
When I list my keys using:
gpg --list-keys
Here is the result:
pub 2048R/0BBBBDB3 2018-02-19
uid user <email>
sub 2048R/4A83B612 2018-02-19
I understand that the sub key doesn't seem to be recognized.
To decrypt you need the private key. Have a look at https://www.gnupg.org/gph/en/manual/x110.html:
If you want to encrypt a message to Alice, you encrypt it using Alice's public key, and she decrypts it with her private key. If Alice wants to send you a message, she encrypts it using your public key, and you decrypt it with your key.
As the documentation states, only the recipient you specify by --recipient when encrypting can decrypt the message.
So in summary:
Encrypting uses the public key of the recicipient
Decrypting uses the private key of the recipient
I managed to have an output of gpg --list-secret-keys
I still can't decrypt the file though. Here is the output of gpg --output doc --decrypt doc.gpg:
gpg: encrypted with 2048-bit RSA key, ID 4A83B612, created 2018-02-19
"user " gpg: decryption failed: secret key not available

Is it possible to (locally) sign a UID using a signing subkey

I'm trying to add a trust for a system account (to stop the nagging message when using it to encrypt data using that key). I've got subkeys setup and an offline master key:
$ gpg --edit-key AAAAAAAA
[...]
Secret key is available.
pub 4096R/AAAAAAAA created: 2015-09-09 expires: never usage: SC
trust: ultimate validity: ultimate
sub 4096R/BBBBBBBB created: 2015-09-09 expires: never usage: E
sub 4096R/CCCCCCCC created: 2015-09-09 expires: never usage: S
sub 4096R/DDDDDDDD created: 2015-09-09 expires: never usage: A
$ gpg --list-secret-keys
sec# 4096R/AAAAAAAA 2015-09-09
uid $NAME <$EMAIL>
ssb 4096R/BBBBBBBB 2015-09-09
ssb 4096R/CCCCCCCC 2015-09-09
ssb 4096R/DDDDDDDD 2015-09-09
If I want to sign a document I can use:
$ gpg --encrypt --sign --recipient AAAAAAAA --local-user CCCCCCCC! --output out.gpg in.gpg
Which uses exactly the specified subkey to sign (although in this case AAAAAAAA is actually unavailable so it couldn't be used in any case). However, if I try and do something similar to lsign another UID:
$ gpg --lsign-key --local-user CCCCCCCC! 'Mentor Root'
pub 4096R/DDDDDDDD created: 2015-09-14 expires: never usage: SC
trust: undefined validity: unknown
sub 4096R/EEEEEEEE created: 2015-09-14 expires: never usage: E
[ unknown] (1). $OTHER_NAME <$OTHER_EMAIL>
pub 4096R/DDDDDDDD created: 2015-09-14 expires: never usage: SC
trust: undefined validity: unknown
Primary key fingerprint: DDDD DDDD DDDD DDDD DDDD DDDD DDDD DDDD DDDD DDDD
$OTHER_NAME <$OTHER_EMAIL>
Are you sure that you want to sign this key with your
key "$NAME <$EMAIL>" (AAAA)
The signature will be marked as non-exportable.
Really sign? (y/N) y
gpg: secret key parts are not available
gpg: signing failed: general error
Key not changed so no update needed.
Is this just a hard limitation of gpg, or is there some step I am missing?
(Or equally possible, am I totally misunderstanding the intent of all this?)
EDIT: Is it simply that the CCCCCCCC subkey does not have the C capability? Is it possible to have a subkey with the C capability (it seems not from cursory searching)?
Only primary keys can have the certification capability C. You cannot sign (ceritfy) keys/user IDs with a subkey.
From RFC 4880, OpenPGP, 12.1 Key Structures:
In a V4 key, the primary key MUST be a key capable of certification.
The subkeys may be keys of any other type.
The math might well allow certification subkeys, but the standard prevents it.

How to display gpg key details without importing it?

I have a copy of the postgresql apt repository gpg key and would like to view the details of the gpg key as it comes in the file. Is this possible without importing it into a key ring?
There are several detail levels you can get when looking at OpenPGP key data: a basic summary, a machine-readable output of this summary or a detailed (and very technical) list of the individual OpenPGP packets.
Basic Key Information
For a brief peak at an OpenPGP key file, you can simply pass the filename as parameter or pipe in the key data through STDIN. If no command is passed, GnuPG tries to guess what you want to do -- and for key data, this is printing a summary on the key:
$ gpg a4ff2279.asc
gpg: WARNING: no command supplied. Trying to guess what you mean ...
pub rsa8192 2012-12-25 [SC]
0D69E11F12BDBA077B3726AB4E1F799AA4FF2279
uid Jens Erat (born 1988-01-19 in Stuttgart, Germany)
uid Jens Erat <jens.erat#fsfe.org>
uid Jens Erat <jens.erat#uni-konstanz.de>
uid Jens Erat <jabber#jenserat.de>
uid Jens Erat <email#jenserat.de>
uid [jpeg image of size 12899]
sub rsa4096 2012-12-26 [E] [revoked: 2014-03-26]
sub rsa4096 2012-12-26 [S] [revoked: 2014-03-26]
sub rsa2048 2013-01-23 [S] [expires: 2023-01-21]
sub rsa2048 2013-01-23 [E] [expires: 2023-01-21]
sub rsa4096 2014-03-26 [S] [expires: 2020-09-03]
sub rsa4096 2014-03-26 [E] [expires: 2020-09-03]
sub rsa4096 2014-11-22 [A] [revoked: 2016-03-01]
sub rsa4096 2016-02-24 [A] [expires: 2020-02-23]
By setting --keyid-format 0xlong, long key IDs are printed instead of the insecure short key IDs:
$ gpg a4ff2279.asc
gpg: WARNING: no command supplied. Trying to guess what you mean ...
pub rsa8192/0x4E1F799AA4FF2279 2012-12-25 [SC]
0D69E11F12BDBA077B3726AB4E1F799AA4FF2279
uid Jens Erat (born 1988-01-19 in Stuttgart, Germany)
uid Jens Erat <jens.erat#fsfe.org>
uid Jens Erat <jens.erat#uni-konstanz.de>
uid Jens Erat <jabber#jenserat.de>
uid Jens Erat <email#jenserat.de>
uid [jpeg image of size 12899]
sub rsa4096/0x0F3ED8E6759A536E 2012-12-26 [E] [revoked: 2014-03-26]
sub rsa4096/0x2D6761A7CC85941A 2012-12-26 [S] [revoked: 2014-03-26]
sub rsa2048/0x9FF7E53ACB4BD3EE 2013-01-23 [S] [expires: 2023-01-21]
sub rsa2048/0x5C88F5D83E2554DF 2013-01-23 [E] [expires: 2023-01-21]
sub rsa4096/0x8E78E44DFB1B55E9 2014-03-26 [S] [expires: 2020-09-03]
sub rsa4096/0xCC73B287A4388025 2014-03-26 [E] [expires: 2020-09-03]
sub rsa4096/0x382D23D4C9773A5C 2014-11-22 [A] [revoked: 2016-03-01]
sub rsa4096/0xFF37A70EDCBB4926 2016-02-24 [A] [expires: 2020-02-23]
pub rsa1024/0x7F60B22EA4FF2279 2014-06-16 [SCEA] [revoked: 2016-08-16]
Providing -v or -vv will even add some more information. I prefer printing the package details in this case, though (see below).
Machine-Readable Output
GnuPG also has a colon-separated output format, which is easily parsable and has a stable format. The format is documented in GnuPG doc/DETAILS file. The option to receive this format is --with-colons.
$ gpg --with-colons a4ff2279.asc
gpg: WARNING: no command supplied. Trying to guess what you mean ...
pub:-:8192:1:4E1F799AA4FF2279:1356475387:::-:
uid:::::::::Jens Erat (born 1988-01-19 in Stuttgart, Germany):
uid:::::::::Jens Erat <jens.erat#fsfe.org>:
uid:::::::::Jens Erat <jens.erat#uni-konstanz.de>:
uid:::::::::Jens Erat <jabber#jenserat.de>:
uid:::::::::Jens Erat <email#jenserat.de>:
uat:::::::::1 12921:
sub:-:4096:1:0F3ED8E6759A536E:1356517233:1482747633:::
sub:-:4096:1:2D6761A7CC85941A:1356517456:1482747856:::
sub:-:2048:1:9FF7E53ACB4BD3EE:1358985314:1674345314:::
sub:-:2048:1:5C88F5D83E2554DF:1358985467:1674345467:::
sub:-:4096:1:8E78E44DFB1B55E9:1395870592:1599164118:::
sub:-:4096:1:CC73B287A4388025:1395870720:1599164118:::
sub:-:4096:1:382D23D4C9773A5C:1416680427:1479752427:::
sub:-:4096:1:FF37A70EDCBB4926:1456322829:1582466829:::
Since GnuPG 2.1.23, the gpg: WARNING: no command supplied. Trying to guess what you mean ... warning can be omitted by using the --import-options show-only option together with the --import command (this also works without --with-colons, of course):
$ gpg --with-colons --import-options show-only --import a4ff2279
[snip]
For older versions: the warning message is printed on STDERR, so you could just read STDIN to split apart the key information from the warning.
Technical Details: Listing OpenPGP Packets
Without installing any further packages, you can use gpg --list-packets [file] to view information on the OpenPGP packets contained in the file.
$ gpg --list-packets a4ff2279.asc
:public key packet:
version 4, algo 1, created 1356475387, expires 0
pkey[0]: [8192 bits]
pkey[1]: [17 bits]
keyid: 4E1F799AA4FF2279
:user ID packet: "Jens Erat (born 1988-01-19 in Stuttgart, Germany)"
:signature packet: algo 1, keyid 4E1F799AA4FF2279
version 4, created 1356516623, md5len 0, sigclass 0x13
digest algo 2, begin of digest 18 46
hashed subpkt 27 len 1 (key flags: 03)
[snip]
The pgpdump [file] tool works similar to gpg --list-packets and provides a similar output, but resolves all those algorithm identifiers to readable representations. It is available for probably all relevant distributions (on Debian derivatives, the package is called pgpdump like the tool itself).
$ pgpdump a4ff2279.asc
Old: Public Key Packet(tag 6)(1037 bytes)
Ver 4 - new
Public key creation time - Tue Dec 25 23:43:07 CET 2012
Pub alg - RSA Encrypt or Sign(pub 1)
RSA n(8192 bits) - ...
RSA e(17 bits) - ...
Old: User ID Packet(tag 13)(49 bytes)
User ID - Jens Erat (born 1988-01-19 in Stuttgart, Germany)
Old: Signature Packet(tag 2)(1083 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 - SHA1(hash 2)
Hashed Sub: key flags(sub 27)(1 bytes)
[snip]
To verify and list the fingerprint of the key (without importing it into the keyring first), type
gpg --show-keys --with-fingerprint <filename>
Edit: on Ubuntu 18.04 (gpg 2.2.4) the fingerprint isn't show with the above command. Use the --with-subkey-fingerprint option instead
gpg --show-keys --with-subkey-fingerprint <filename>
I seem to be able to get along with simply:
$gpg <path_to_file>
Which outputs like this:
$ gpg /tmp/keys/something.asc
pub 1024D/560C6C26 2014-11-26 Something <something#none.org>
sub 2048g/0C1ACCA6 2014-11-26
The op didn't specify in particular what key info is relevant. This output is all I care about.
You may also use --keyid-format switch to show short or long key ID:
$ gpg2 -n --with-fingerprint --keyid-format=short --show-keys <filename>
which outputs like this (example from PostgreSQL CentOS repo key):
pub dsa1024/442DF0F8 2008-01-08 [SCA] │
Key fingerprint = 68C9 E2B9 1A37 D136 FE74 D176 1F16 D2E1 442D F0F8 │ honor-keyserver-url
uid PostgreSQL RPM Building Project <pgsqlrpms-hackers#pgfoundry.org> │ When using --refresh-keys, if the key in question has a preferred keyserver URL, then use that
sub elg2048/D43F1AF8 2008-01-08 [E]
The option --list-packets parses pgp data from a file and outputs its structure - in a very technical way, though. When parsing a public key, you can easily extract the user ids and the key ids of the signatures.
Be wary that this command only parses the data format, it does no validation of signatures or similar things.
To get the key IDs (8 bytes, 16 hex digits), this is the command which worked for me in GPG 1.4.16, 2.1.18 and 2.2.19:
gpg --list-packets <key.asc | awk '$1=="keyid:"{print$2}'
To get some more information (in addition to the key ID):
gpg --list-packets <key.asc
To get even more information:
gpg --list-packets -vvv --debug 0x2 <key.asc
The command
gpg --dry-run --import <key.asc
also works in all 3 versions, but in GPG 1.4.16 it prints only a short (4 bytes, 8 hex digits) key ID, so it's less secure to identify keys.
Some commands in other answers (e.g. gpg --show-keys, gpg --with-fingerprint, gpg --import --import-options show-only) don't work in some of the 3 GPG versions above, thus they are not portable when targeting multiple versions of GPG.
When I stumbled up on this answer I was looking for a way to get an output that is easy to parse. For me the option --with-colons did the trick:
$ gpg --with-colons file
sec::4096:1:AAAAAAAAAAAAAAAA:YYYY-MM-DD::::Name (comment) email
ssb::4096:1:BBBBBBBBBBBBBBBB:YYYY-MM-DD::::
Documentation can be found here.
pgpdump (https://www.lirnberger.com/tools/pgpdump/) is a tool that you can use to inspect pgp blocks.
It is not user friendly, and fairly technical, however,
it parses public or private keys (without warning)
it does not modify any keyring (sometimes it is not so clear what gpg does behind the hood, in my experience)
it prints all packets, specifically userid's packets which shows the various text data about the keys.
pgpdump -p test.asc
New: Secret Key Packet(tag 5)(920 bytes)
Ver 4 - new
Public key creation time - Fri May 24 00:33:48 CEST 2019
Pub alg - RSA Encrypt or Sign(pub 1)
RSA n(2048 bits) - ...
RSA e(17 bits) - ...
RSA d(2048 bits) - ...
RSA p(1024 bits) - ...
RSA q(1024 bits) - ...
RSA u(1020 bits) - ...
Checksum - 49 2f
New: User ID Packet(tag 13)(18 bytes)
User ID - test (test) <tset>
New: Signature Packet(tag 2)(287 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 - SHA256(hash 8)
Hashed Sub: signature creation time(sub 2)(4 bytes)
Time - Fri May 24 00:33:49 CEST 2019
Hashed Sub: issuer key ID(sub 16)(8 bytes)
Key ID - 0x396D5E4A2E92865F
Hashed Sub: key flags(sub 27)(1 bytes)
Flag - This key may be used to certify other keys
Flag - This key may be used to sign data
Hash left 2 bytes - 74 7a
RSA m^d mod n(2048 bits) - ...
-> PKCS-1
unfortunately it does not read stdin : /
For newer versions of gngpg version 2.2.8 and above:
If you want only want to get the short or long fingerprint of the key without importing the key and without redirecting stderr to stdout 2>&1:
(i.e. when you have scripts verifying the fingerprint before proceeding like with ansible)
I have included a way with --with-colons and one without depending on your scripting preferences.
To get short format key ID
short key id format (using --show-keys and --with-colons):
gpg --show-keys --with-colons keyfile.key | awk -F':' '$1=="pub"{print $5}'
short key id format (using --list-packets):
gpg --list-packets keyfile.key | awk '$1=="keyid:"{print$2}'
To get long format key ID
long key id format (using --show-keys and --with-colons):
gpg --show-keys --with-colons keyfile.key | awk -F':' '$1=="fpr"{print $10}'
long key id format (using --show-keys):
gpg --show-keys keyfile.key | sed -nr 's/^([ ]+)([0-9A-Z]{40}$)/\2/p'

PVK2PFX Error 0x80070490 - Cannot find certificates that match the key

We got our new certificate (*.cer) file from Thawte, and i went through our standard procedures to allow it for use with code signing.
If i use our old (working) certificate:
Convert certificate (.cer) into Software Publishing Certificate (.spc)
>Cert2Spc.exe Avatar.cer Avatar.spc
Succeeded
Combine our private key file (*.pvk) with the SPC into a PFX:
>pvk2pfx.exe -pvk Avatar.pvk -spc Avatar.spc -pfx Avatar.pfx -f
prompts for private key file password, enter it, click OK
And we're good to go; ready to use signtool.
We now have our new certificate, and i follow the same procedure:
Convert certificate (.cer) into Software Publishing Certificate (.spc)
>Cert2Spc.exe Avatar.cer Avatar.spc
Succeeded
Combine our private key file (*.pvk) with the SPC into a PFX:
>pvk2pfx.exe -pvk Avatar.pvk -spc Avatar.spc -pfx Avatar.pfx -f
prompts for private key file password, enter it, click OK
ERROR: Cannot find certificates that match the key.
(Error Code = 0x80070490).
What's going wrong?
Notes:
we've used the same private key file (*.pvk) for a decade
this year Thawte gave us a 2-year certificate; rather than the usual 1-year
this year Thawte changed their signing certificate from Thawte Code Signing CA to Thawte Code Signing CA - G2
Google says that nobody has ever gotten the error Cannot find certificates to match the key.
The Windows SDK only contains two references to the error code 0x80070490:
Visual Foxpro for Windows header file (vfwmsgs.h):
//
// MessageId: E_PROP_ID_UNSUPPORTED
//
// MessageText:
//
// The specified property ID is not supported for the specified property set.%0
//
#define E_PROP_ID_UNSUPPORTED ((HRESULT)0x80070490L)
Which is almost certainly a red herring; Foxpro?
commented out code in the RSS screensaver sample (RssItem.cs)
// "Element not found. (Exception from HRESULT: 0x80070490)"
Also almost certainly a red-herring; XML?
decimal version of 0x80070490 is -2147023728
Turns out that this year we were given a new private key.
Well, you're not given a private key, the certificate+key is fetched through the browser and stored in a certificate store. From there we can export a .PFX (A pfx contains a certificate and a private key).
With this PFX exported from the browser's certificate store, we can use it directly to sign code with signtool.
Note: We were actually gluttons for punishment, and went through steps:
+--[.pfx]---+ +--[.cer]---+ +--[.spc]---+ +--[.pfx]---+
|Certificate|====>|Certificate|====>|Software |=========> |Certificate|
| + | +-----------+ |Publishing | | + |
|Private Key|==+ + |Certificate| +=====> |Private Key|
+-----------+ | +-----------+ | +-----------+
| |
| |
| +--[.pem]---+ +--[.pvk]---+ |
+=>|Private Key| ==> |Private Key|===+
+-----------+ +-----------+
But all that route gave us was a private key file (*.pvk) that wasn't protected with a password; so signtool could run without user interaction.
But the answer to this question was: The private key doesn't match the certificate.

Resources