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
| Feature | Value |
|---|---|
| Full name | GnuPG / OpenPGP data (encrypted message, signature or keyring) |
| File extension | .gpg |
| MIME type | application/pgp-encrypted |
| Format type | Binary OpenPGP packet stream |
| Developer | GnuPG (FSF / g10 Code); OpenPGP standard by the IETF |
| Introduced | GnuPG 1.0, 1999 |
| Standard | OpenPGP: RFC 2440 (1998), RFC 4880 (2007), RFC 9580 (2024) |
| Open standard | Yes |
| Container structure | Sequence of tag-length-value packets |
| First byte | packet tag, bit 7 always set (e.g. 0x84, 0x85, 0xC1, 0x99) |
| Magic number | None fixed; identify via GnuPG, not a signature |
| Text-armored form | .asc (Base64, -----BEGIN PGP MESSAGE-----) |
| Common ciphers | AES-128/256 in AEAD/SEIPD; session key wrapped per recipient |
| Keyring files | pubring.gpg, legacy secring.gpg, trustdb.gpg |
| Modern key store | pubring.kbx keybox (GnuPG 2.1+, 2014) |
| Primary tool | GnuPG (gpg); GUIs: Gpg4win/Kleopatra, GPG Suite |
| Related extensions | .asc, .sig, .pgp, .key, .kbx |
| Specification | RFC 9580 (OpenPGP) |
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 octet | Meaning |
|---|---|
| 0–191 | the length is that value (one octet total) |
| 192–223 | two octets: ((b1−192)<<8) + b2 + 192 |
| 255 | four more octets: a 32-bit big-endian length |
| 224–254 | a 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
- RFC 9580 — OpenPGP (current standard)
- GnuPG — official site and documentation
- Gpg4win — GnuPG for Windows (Kleopatra)
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.