GPG File Documentation


Summary

A .gpg file is binary OpenPGP data produced by GnuPG (the GNU Privacy Guard). Most are encrypted messages, but the extension is also used for binary signatures and for keyring files like pubring.gpg. Its MIME type is application/pgp-encrypted. To read an encrypted one you need GnuPG plus the passphrase or private key: run gpg -d file.gpg. You cannot open it by renaming; the bytes stay ciphertext until GnuPG decrypts them. The ASCII-armored text form uses .asc.

Technical details

FeatureValue
Full nameGnuPG / OpenPGP data (encrypted message, signature or keyring)
File extension.gpg
MIME typeapplication/pgp-encrypted
Format typeBinary OpenPGP packet stream
DeveloperGnuPG (FSF / g10 Code); OpenPGP standard by the IETF
IntroducedGnuPG 1.0, 1999
StandardOpenPGP: RFC 2440 (1998), RFC 4880 (2007), RFC 9580 (2024)
Open standardYes
Container structureSequence of tag-length-value packets
First bytepacket tag, bit 7 always set (e.g. 0x84, 0x85, 0xC1, 0x99)
Magic numberNone fixed; identify via GnuPG, not a signature
Text-armored form.asc (Base64, -----BEGIN PGP MESSAGE-----)
Common ciphersAES-128/256 in AEAD/SEIPD; session key wrapped per recipient
Keyring filespubring.gpg, legacy secring.gpg, trustdb.gpg
Modern key storepubring.kbx keybox (GnuPG 2.1+, 2014)
Primary toolGnuPG (gpg); GUIs: Gpg4win/Kleopatra, GPG Suite
Related extensions.asc, .sig, .pgp, .key, .kbx
SpecificationRFC 9580 (OpenPGP)
File signature (packet tags)
C1 · 85 / 84 · C3 / 8C · 99 / 98 · 88 / 89

A .gpg has no single fixed magic number. Its first byte is an OpenPGP packet tag, always with bit 7 set. Which tag appears depends on the content: a public-key-encrypted message typically starts with a Public-Key Encrypted Session Key packet (tag 1, legacy byte 0x85/0x84, current-format 0xC1); a passphrase-encrypted file starts with a Symmetric-Key Encrypted Session Key packet (tag 3, 0x8C/0xC3); a signature with tag 2 (0x88/0x89/0xC2); a public key or keyring with tag 6 (0x99/0x98/0xC6). Identify a .gpg by feeding it to GnuPG, not by matching bytes.

What is a .gpg file?

A .gpg file is binary data created by GnuPG (the GNU Privacy Guard), the standard free implementation of the OpenPGP standard. GnuPG shipped its 1.0 release in 1999, and OpenPGP itself is an IETF standard: RFC 2440 (1998), then RFC 4880 (2007), and now RFC 9580, published in 2024. The extension is used for several different OpenPGP objects, but they are all the same underlying thing: a stream of OpenPGP packets. What differs is which packets are inside.

Three meanings dominate. Most commonly a .gpg is an encrypted file or message, sealed either to a recipient’s public key or with a passphrase. Second, it can be a binary signature proving a file is authentic. Third, it can be a GnuPG keyring such as pubring.gpg, the meaning some file-type databases pick as the headline even though it is the least common thing users actually double-click. The plain-text counterpart of a binary .gpg is the ASCII-armored .asc; the sections below describe the packet framing they share, then each meaning in turn.

The packet tag byte: how OpenPGP frames data

An OpenPGP file is not one blob. It is a sequence of self-describing packets, each introduced by a header that says what kind of packet it is and how long it is. The first byte of every packet is the packet tag, and RFC 9580 fixes its top bit: bit 7 is always 1. That single rule is why the first byte of a genuine .gpg is never a printable ASCII character below 0x80; it is a high-bit-set tag such as 0x85, 0x8C, 0xC1 or 0x99.

first octet of a packet:
  bit 7      = 1            always
  bit 6      = format       1 = OpenPGP (current) format
                            0 = Legacy format
  OpenPGP format:  bits 5-0 = packet type ID (0-63)
  Legacy format:   bits 5-2 = packet type ID (0-15)
                   bits 1-0 = length-type

Bit 6 selects the header dialect. In the current (OpenPGP) format the low six bits hold the packet type ID directly, so tags range 0–63. In the older legacy format only bits 5–2 carry the type (0–15) and the bottom two bits encode how the length is stored. GnuPG still writes legacy-format packets by default for wide compatibility, which is why you see both 0x85 (legacy tag 1) and 0xC1 (current-format tag 1) in the wild for the same kind of packet.

Body length encoding

After the tag comes the packet’s body length, and OpenPGP encodes it compactly so short packets cost one byte. In the current format the rules are:

First length octetMeaning
0–191the length is that value (one octet total)
192–223two octets: ((b1−192)<<8) + b2 + 192
255four more octets: a 32-bit big-endian length
224–254a partial body length (a power-of-two chunk, used for streaming)

Partial lengths let GnuPG start emitting an encrypted stream before it knows the total size, splitting the body into power-of-two chunks with a final non-partial length to close it. A reader that understands the tag byte and these length rules can walk the whole packet stream, skip packets it does not recognise, and hand each one to the right handler, exactly the way it does for the encrypted, signature and key cases below.

The encrypted-message case: PKESK, SKESK and SEIPD

The high-intent .gpg is an encrypted file, and it is built from a small set of packets in a fixed order. OpenPGP uses hybrid encryption: the actual data is encrypted once with a random symmetric session key, and that session key is then wrapped so the intended party can recover it.

public-key encrypted file:
  [PKESK  tag 1]   session key wrapped to recipient's public key
  [PKESK  tag 1]   ... one per recipient ...
  [SEIPD  tag 18]  the ciphertext + integrity check (AEAD/MDC)

passphrase encrypted file:
  [SKESK  tag 3]   session key derived from the passphrase via S2K
  [SEIPD  tag 18]  the ciphertext + integrity check

A Public-Key Encrypted Session Key packet (tag 1) holds the session key encrypted to one recipient’s public key; a file encrypted to three people carries three of them, and each recipient’s GnuPG tries the ones matching its key IDs. A Symmetric-Key Encrypted Session Key packet (tag 3) instead stores the parameters of a string-to-key (S2K) function that turns your passphrase into the session key, which is what gpg --symmetric produces. Either way the payload lands in a Symmetrically Encrypted and Integrity Protected Data packet (SEIPD, tag 18): the ciphertext plus a built-in integrity check, so tampering is detected on decrypt. Running gpg -d file.gpg unwraps the session key (via your private key or your passphrase), decrypts the SEIPD, verifies the integrity tag, and writes out the plaintext. There is no way to reach the plaintext without that key or passphrase; renaming the file changes nothing because the bytes are ciphertext.

The signature case

A .gpg can also be a signature: a Signature packet (tag 2) that binds a hash of some data to the signer’s key. The packet records the signature version, the public-key and hash algorithms, the signer’s key ID (or fingerprint issuer subpacket), a timestamp, and the signature value itself. A detached signature is a standalone .gpg (or .sig) that travels next to the file it signs; verification recomputes the file’s hash and checks it against the signature with the signer’s public key (gpg --verify file.gpg data). An inline signature wraps the data and the signature together. The text-armored equivalents carry the same packets inside a -----BEGIN PGP SIGNATURE----- block.

The keyring case: pubring.gpg, secring.gpg and trustdb.gpg

Historically GnuPG stored collections of keys as loose .gpg files inside the user’s ~/.gnupg directory. pubring.gpg is a public keyring: a concatenation of Public-Key packets (tag 6), their Public-Subkey packets (tag 14), User ID packets (tag 13) and the certifying signatures that bind names to keys. secring.gpg was the matching secret keyring, and trustdb.gpg is the trust database recording how much you trust each key’s owner to certify others.

Modern GnuPG (2.1 and later, from 2014) changed this. Public keys now live in a pubring.kbx keybox, and secret keys are held one-per-file by the gpg-agent in a private key store, so a loose secring.gpg is now legacy. These files are managed by GnuPG’s own commands (gpg --list-keys, --import, --export), not opened by hand; editing one directly corrupts it.

.gpg versus .asc: binary and armored are the same data

A binary .gpg and an armored .asc hold identical OpenPGP packets; the only difference is the outer encoding. ASCII armor Base64-encodes the same bytes and wraps them in -----BEGIN PGP MESSAGE----- / -----END PGP MESSAGE----- lines with a CRC, so the data survives email bodies, chat and copy-paste that would mangle raw binary. GnuPG converts between the two without re-encrypting: gpg --enarmor / --dearmor switch encodings, and adding --armor to an encrypt or sign command emits the .asc form directly. Decryption and verification work the same on either. Related extensions .pgp and, for symmetric-key exchange, PEM-wrapped material in .pem files sit in the same ecosystem.

Security: protecting keys and avoiding fake decryptors

The .gpg format is a security tool, not a threat: the file is encrypted or signed OpenPGP data and contains no executable code of its own. The real cautions are about keys and where you decrypt. A secret-key .gpg or a legacy secring.gpg holds your private keys; anyone with that file and its passphrase can decrypt everything sent to you and sign as you, so never share it, and protect it with a strong passphrase (the S2K function only slows a guessing attack, it does not stop one against a weak passphrase). Always decrypt locally with GnuPG. Websites that ask you to upload a .gpg and paste your passphrase or private key are the standard scam; a service that does not already hold your key cannot decrypt your file, so any “online GPG decryptor” that claims to is either useless or harvesting secrets. Finally, a successful decrypt only means the ciphertext was valid: the recovered plaintext (which might be an executable or an Office document) still carries whatever risk that file type normally would, so treat it accordingly.

References