Magic numbers for keyring files?
roam at ringlet.net
Wed Sep 25 16:14:52 CEST 2013
On Wed, Sep 25, 2013 at 09:18:23AM -0400, Robert J. Hansen wrote:
> I'm working on adding support for GnuPG keyrings to a file carver (a
> forensic tool that recovers data from damaged filesystems, or recovers
> things that have been deleted but not overwritten). Detecting an
> ASCII-armored keyblock is pretty easy: look for the "BEGIN PGP PUBLIC"
> header. Binary, though, is still an unsolved question.
> Before I start diving into code to find out if the keyring has a
> specific binary header I can detect, I figured I'd ask on-list. :)
> Does anyone know of any magic numbers for GnuPG keyring files?
AFAIK, a GnuPG keyring (as well as a PGP Inc. keyring) is just a
concatenation of the (binary representation of the) public/private keys
stored there. Thus, the file format you're looking for is the file
format of an OpenPGP key as defined by, yeah, you guessed it, RFC 4880
Of course, I could be wrong, but I really don't think that GnuPG stores
anything more than that - and an easy way to test that is to point
Bernhard Link's gpg2txt - https://alioth.debian.org/projects/gpg2txt/ or
https://code.launchpad.net/gpg2txt - or Kazu Yamamoto's pgpdump -
http://www.mew.org/~kazu/proj/pgpdump/en/ - at your secring.gpg or
pubring.gpg file; they will display a sequence of packets comprising one
or more OpenPGP keys.
So what you need to look for is sequences of bytes matching the OpenPGP
format; this usually means packets of type 5 for private keys or 6 for
public ones. Unfortunately the first bytes will vary with 1. the format
version and 2. the packet (key) length, so there is no exact marker.
Still, file(1) does it somehow; you might want to look at file's source,
at its magic database, to see the heuristics it uses.
In general I would guess it could be something like (all in hex):
- 94 xx: xx bytes of private key data, tag 5, old format packet length
- 95 xx yy: xx*256+yy bytes of private key data, tag 5, old length
- 96 xx yy zz: xx*65536 + yy*256 + zz bytes of the same
- C5 xx: xx (less than 192) bytes of private key data, tag 5, new length
- C5 xx yy: (xx-192) * 256 + yy bytes of private key data, tag 5, new
- C5 FF xx yy zz tt: up to 4 GB of private key data, tag 5, new
- 98 xx: xx bytes of public key data, tag 6, old format packet length
- 99 xx yy: xx*256+yy bytes of public key data, tag 6, old length
- 9A xx yy zz: xx*65536 + yy*256 + zz bytes of the same
- C6 xx: xx (less than 192) bytes of public key data, tag 6, new length
- C6 xx yy: (xx-192) * 256 + yy bytes of public key data, tag 6, new
- C6 FF xx yy zz tt: up to 4 GB of public key data, tag 6, new
Then you should match the first bytes of the packet itself; it would
probably start with a 04 (version) xx yy zz tt (timestamp), algorithm,
Hope that helps :)
Peter Pentchev roam at ringlet.net roam at FreeBSD.org p.penchev at storpool.com
PGP key: http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint 2EE7 A7A5 17FC 124C F115 C354 651E EFB0 2527 DF13
Hey, out there - is it *you* reading me, or is it someone else?
-------------- next part --------------
A non-text attachment was scrubbed...
Size: 836 bytes
Desc: Digital signature
More information about the Gnupg-users