Analysing PGP Identities

Getting Information About a Key
Each PGP "key" actually contains a few user identities. Usually one user identity for each e-mail address that you use.

Let's say you got a file pgpkey.asc, with a GPG block, you can analyse it:

% gpg pgpkey.asc pub 1024D/B804CF07 2006-02-05 Freek Dijkstra  uid                           Freek Dijkstra  uid                           [jpeg image of size 5225] sub 2048g/2C33CF18 2006-02-05

Or if you have it in your PGP database (~/.gnupg/pubring.gpg and ~/.gnupg/secring.gpg):

% gpg --list-keys 0xB804CF07 pub  1024D/B804CF07 2006-02-05 uid                 Freek Dijkstra  uid                 Freek Dijkstra  uid                 [jpeg image of size 5225] sub  2048g/2C33CF18 2006-02-05

Or sightly more detailed:

% gpg --edit-key 0xB804CF07 list quit Secret key is available. pub 1024D/B804CF07  created: 2006-02-05  expires: never       usage: SCA trust: ultimate     validity: ultimate sub 2048g/2C33CF18  created: 2006-02-05  expires: never       usage: E    [ultimate] (1). Freek Dijkstra  [ultimate] (2) Freek Dijkstra  [ultimate] (3) [jpeg image of size 5225]

However, this is not all there is in a key. It is incomplete and imprecise. The fixed list mode lists more records.

% gpg --with-colons --fixed-list-mode --with-fingerprint --list-keys 0xB804CF07 tru::0:1203517710:1221409883:3:1:5 pub:u:1024:17:567C3C2DB804CF07:1139175758:::u:::scaESCA: fpr:::::::::AE237158C1D0F7C92641C42F567C3C2DB804CF07: uid:u::::1143128254::1B0041418A2E2FA99674E07A7E993B9B9873AC12::Freek Dijkstra : uid:u::::1143128256::86FADB7D717FC5CF194351A038F46492B6C26679::Freek Dijkstra : uat:u::::1143128256::23C52AEB53F543FB98FF68E09BCF7D2C16A955B2::1 5244: sub:u:2048:16:C63F06AD2C33CF18:1139175851::::::e: fpr:::::::::9CD4EACFA20E38431608E9F6C63F06AD2C33CF18:

In addition, list-secret-keys lists the secret keys:

% gpg --with-colons --fixed-list-mode --with-fingerprint --list-secret-keys 0xB804CF07 sec::1024:17:567C3C2DB804CF07:1139175758::::::scaESCA:::: ssb::2048:16:C63F06AD2C33CF18:1139175851::::::e::::

Finally, the key also contains signatures (of others who signed this key):

% gpg --with-colons --fixed-list-mode --list-sigs 0xB804CF07 uid:u::::1143128254::1B0041418A2E2FA99674E07A7E993B9B9873AC12::Freek Dijkstra : sig:::17:567C3C2DB804CF07:1139179009::::Freek Dijkstra :13x: sig:::17:B22BAE0CA2B2144F:1139323364::::Hans Boer <hansboer@example.org>:13x: sig:::17:810C449D09E7E513:1139588799::::Jane Doe <jd@example.net>:13x: sig:::17:BA25519B0D848FDA:1139757781::::Kees Visser <visser@example.com>:10x: uid:u::::1143128256::86FADB7D717FC5CF194351A038F46492B6C26679::Freek Dijkstra <fdijkstr@science.uva.nl>: sig:::17:567C3C2DB804CF07:1139178112::::Freek Dijkstra <freek@macfreek.nl>:13x: sig:::17:B22BAE0CA2B2144F:1139323364::::Hans Boer <hansboer@example.org>:13x: sig:::17:810C449D09E7E513:1139588801::::Jane Doe <jd@example.net>:13x: uat:u::::1143128256::23C52AEB53F543FB98FF68E09BCF7D2C16A955B2::1 5244: sig:::17:F0B9926FC6C9293C:1143467395::::Piet Jansma <jansma@example.net>:10x: sig:::17:567C3C2DB804CF07:1143128256::::Freek Dijkstra <freek@macfreek.nl>:13x: sub:u:2048:16:C63F06AD2C33CF18:1139175851::::::e: sig:::17:567C3C2DB804CF07:1139175851::::Freek Dijkstra <freek@macfreek.nl>:18x:

Analysing the Contents of the Key
PGP records as listed above can be analysed by hand or the lpgpdump tool.

The authoritative information for manual analysis can be found at the file /usr/share/doc/gnupg/DETAILS.

If we analyse the key listed above, there are 10 entries in total:
 * tru: trust database information
 * pub, sec, fpr: public key, secret key, and fingerprint
 * uid: user id (twice)
 * uat: user attribute, in this case a picture
 * sub, ssb, fpr: subkey, secret subkey, and fingerprint
 * sig: signatures

A detailed analysis gives:

tru::0:1203517710:1221409883:3:1:5

Trust database, created 20 Feb 2008 (timestamp 1203517710), expiration date 14 Sep 2008 (timestamp 1221409883). The meaning of the other integers is unclear to me.

pub:u:1024:17:567C3C2DB804CF07:1139175758:::u:::scaESCA: sec::1024:17:567C3C2DB804CF07:1139175758::::::scaESCA:::: fpr:::::::::AE237158C1D0F7C92641C42F567C3C2DB804CF07:

(Primary) Public key (pub), private key (sec) and fingerprint (fpr). Created at 05 Feb 2006 (timestamp 1139175758 = seconds since 1 jan 1970). The full key ID is 0x567C3C2DB804CF07, often abbreviated to 0xB804CF07. Note that the ID are simply the last characters of the fingerprint. Key length is 1024 bits, DSA algorithm (algorithm 17). The 'u' signifies that this key is 'ultimately trusted': it is my own key.

pgpdump lists the following information about the public and secret keys (the salt is altered before publication here):

Old: Public Key Packet(tag 6)(418 bytes) Ver 4 - new Public key creation time - Sun Feb 5 22:42:38 CET 2006 Pub alg - DSA Digital Signature Algorithm(pub 17) DSA p(1024 bits) - ... DSA q(160 bits) - ... DSA g(1022 bits) - ... DSA y(1024 bits) - ... Old: Secret Key Packet(tag 5)(481 bytes) Ver 4 - new Public key creation time - Sun Feb 5 22:42:38 CET 2006 Pub alg - DSA Digital Signature Algorithm(pub 17) DSA p(1024 bits) - ... DSA q(160 bits) - ... DSA g(1022 bits) - ... DSA y(1024 bits) - ... Sym alg - CAST5(sym 3) Iterated and salted string-to-key(s2k 3): Hash alg - SHA1(hash 2) Salt - 01 23 45 67 89 ab cd ef 		Count - 65536(coded count 96) IV - 01 23 45 67 89 ab cd ef 	Encrypted DSA x 	Encrypted SHA1 hash

The characters at the end are in particular relevant. They signify the capabilities of the key:
 * e = encrypt/decrypt (decrypt with your private key of a message you received)
 * s = sign (sign data. For example a file or to send signed e-mail)
 * c = certify (sign another key, establishing a trust-relation)
 * a = authentication (log in to SSH with a PGP key; this is relatively new usage)

This primary subkey can be used for signing (s), certifying (c) and authentication (a). It can not be used for encryption (e) (That is never possible for DSA algorithm keys). Since this is the primary key, the capabilities of the whole key (all subkeys) are listed as well using capital letters: Encryption (E), Signing (S), Certification (C), and authentication (A). Since this key can't to encryption, we must conclude that there is another subkey that can do that.

sub:u:2048:16:C63F06AD2C33CF18:1139175851::::::e: ssb::2048:16:C63F06AD2C33CF18:1139175851::::::e:::: fpr:::::::::9CD4EACFA20E38431608E9F6C63F06AD2C33CF18:

And here is that subkey for encryption. We have a public subkey (sub), private subkey (ssb) and fingerprint (fpr). This is an Elgamal (algorithm 16) key of 2048 bits, created at 05 Feb 2006 (timestamp 1139175851). And indeed it can only be used for encryption (e). Note that the Key ID of this secondary key (0xC63F06AD2C33CF18) is different from the primary key (0x567C3C2DB804CF07). Also note that again, the Key ID are again the last chars of the fingerprint.

uid:u::::1143128254::1B0041418A2E2FA99674E07A7E993B9B9873AC12::Freek Dijkstra <freek@macfreek.nl>: uid:u::::1143128256::86FADB7D717FC5CF194351A038F46492B6C26679::Freek Dijkstra <fdijkstr@science.uva.nl>: uat:u::::1143128256::23C52AEB53F543FB98FF68E09BCF7D2C16A955B2::1 5244:

Beside subkeys, my PGP key also contains identities. In this case, two email addresses in uid records, and a photo in a uat record. The e-mail address records were created at 23 Mar 2006 (timestamp 1143128254). Since I know I added the picture later than the e-mail addresses, I can only conclude that the records are rewritten (or the timestamp is reset) after each addition of a uid or uat.

The User-ID field for the uid records is pretty much self-explanatory. for the uat it is a count of subfields and size of the field. In this case there is one image of 5244 bytes. The 'u' again means that the keys are ultimately trusted: they are from my own key.

uid:u::::1143128254::1B0041418A2E2FA99674E07A7E993B9B9873AC12::Freek Dijkstra <freek@macfreek.nl>: sig:::17:567C3C2DB804CF07:1139179009::::Freek Dijkstra <freek@macfreek.nl>:13x: sig:::17:B22BAE0CA2B2144F:1139323364::::Hans Boer <hansboer@example.org>:13x: sig:::17:810C449D09E7E513:1139588799::::Jane Doe <jd@example.net>:13x: sig:::17:BA25519B0D848FDA:1139757781::::Kees Visser <visser@example.com>:10x: uid:u::::1143128256::86FADB7D717FC5CF194351A038F46492B6C26679::Freek Dijkstra <fdijkstr@science.uva.nl>: sig:::17:567C3C2DB804CF07:1139178112::::Freek Dijkstra <freek@macfreek.nl>:13x: sig:::17:B22BAE0CA2B2144F:1139323364::::Hans Boer <hansboer@example.org>:13x: sig:::17:810C449D09E7E513:1139588801::::Jane Doe <jd@example.net>:13x: uat:u::::1143128256::23C52AEB53F543FB98FF68E09BCF7D2C16A955B2::1 5244: sig:::17:F0B9926FC6C9293C:1143467395::::Piet Jansma <jansma@example.net>:10x: sig:::17:567C3C2DB804CF07:1143128256::::Freek Dijkstra <freek@macfreek.nl>:13x: sub:u:2048:16:C63F06AD2C33CF18:1139175851::::::e: sig:::17:567C3C2DB804CF07:1139175851::::Freek Dijkstra <freek@macfreek.nl>:18x:

Finally, the key lists the keys signs other people made for this key. It does not list signatures for other keys, made with this key. There are signatures for each uid or uat. Only the order of the signatures allows us to determine which uid or uat was signed. All keys listed here are signed with DSA. The key ID, signing date and User ID are self-explanatory. The 10th field represent the signature class and scope. 'x' means that the signature is exportabe ('l' would mean a local signature). The signature class denote the certification level, how well the identity was checked:


 * Class 10 means certification level 0 - No particular claim is made (generic certification)
 * Class 11 means certification level 1 - No verification of identity (persona certification)
 * Class 12 means certification level 2 - Casual verification of identity (casual certification)
 * Class 13 means certification level 3 - Extensive verification of identity (positive certification)
 * Class 18 means it is a self-signature (signing of the uid with the key itself)

Classes 30-38 are used for revocation.

Class 10 is usually denoted as by a user interface as "sig", while class 13 is denoted as "sig3". Users can choose the level of certification using the --ask-cert-level</tt> option in the command line.

Not all fields are used for each record. For example, uid and uat records have expiration dates, like any other record. However, only field 10 (User-ID) is used. So it is not possible to set an expiration date for uid or uat in practice.

Analyzing Encrypted Messages
An encrypted PGP message may have multiple recipients, who can all decrypt the message with their own private key. Even a message destined for one person is by default also encrypted with the public key of the sender, so the sender can still read the message (otherwise, this would not be possible).

For efficiency, the content of a PGP message is not encrypted with a public key, but with a computationally much faster (symmetric) key. This symmetric key is then encrypted with the public key of each recipient, so that each recipient can find the symmetric key. Not only is this computationally faster for longer messages, it also reduces the size of the message (only the symmetric key needs to be encrypted multiple times, not the whole message).

To analyze a PGP message:

% gpg --list-packets --list-only mymessage.txt.asc :pubkey enc packet: version 3, algo 16, keyid C5AC471B44F5C28F data: [4093 bits] data: [4096 bits] :pubkey enc packet: version 3, algo 1, keyid 5C282F9C6F7A0B5E data: [2048 bits] :pubkey enc packet: version 3, algo 16, keyid 862787EA0E886576 data: [2046 bits] data: [2048 bits] :encrypted data packet: length: 3191 mdc_method: 2 gpg: encrypted with 2048-bit RSA key, ID 44F5C28F, created 2010-06-15 "John Doe <john@example.com>" gpg: encrypted with 4096-bit ELG-E key, ID 6F7A0B5E, created 2007-01-05 "Jane Doe <jane@example.net>"

The 3191 byte package contains the encrypted message. The three pubkeys contain the encrypted key for the two recipients and the original sender. The two records at the end provide details of the two recipients by looking up in the local key ring.

The message in the above example is signed, but until the data packet is decrypted, there is no way to tell this.