Home / Alt manpages / gpgsplit(1)

  • gpgsplit(1)
  • User command
  • linux

Split OpenPGP packets safely with gpgsplit

You will split an OpenPGP message into one file per packet, with names that show each packet's sequence and type. The original input remains available for comparison, and you can send the unsplit packet stream to standard output when you need a pipeline. Allow about ten minutes for a normal inspection, plus time to identify the packet types in a large message.

This guide describes GnuPG 2.4.4 from the installed gnupg-utils package, version 2.4.4-2ubuntu17.6. The local manual page is brief, so the examples below also check the behaviour of the installed binary. Other GnuPG releases can differ in diagnostics or the exact output names.

1. Check the installed command

Confirm that gpgsplit is available and record its version before using an example in a script:

$ command -v gpgsplit
/usr/bin/gpgsplit
$ gpgsplit --version
gpgsplit (GnuPG) 2.4.4

The command is supplied by gnupg-utils. It reads binary OpenPGP packets, not an arbitrary text file and not an ASCII-armoured block as plain text. If your input is armoured, de-armor it with the appropriate GnuPG operation first, or use the original binary message if you have it.

Checkpoint

Do not use sudo merely because the tool handles keys. Reading an archive and writing a working directory normally needs no elevated privilege. Use an account that can read the input and write the destination.

2. Split into a dedicated directory

Make a new, empty destination and run gpgsplit with the binary message as its argument:

$ mkdir -p /path/to/gpgsplit-output
$ cd /path/to/gpgsplit-output
$ gpgsplit /path/to/message.pgp

With no options, the program writes one file per packet in the current directory. A test public-key export produced names like these:

$ ls -l
000001-006.public_key
000002-013.user_id
000003-002.sig

The first number is the packet sequence, the middle number is the packet tag, and the suffix describes the packet type. The exact sequence depends on the input. A message may contain signatures, user IDs, literal data, compressed data or key packets in a different order.

Use an empty directory because generated names are predictable. gpgsplit is an inspection tool, but a careless run in a directory containing similarly named files can make the result confusing and can risk a collision. Do not delete an existing output set until you have checked that it belongs to this run. If a run is interrupted, keep the original message and remove only the newly created packet files after checking their names.

Checkpoint

Verify that the source still exists and that packet files were created:

$ test -r /path/to/message.pgp && printf '%s\n' 'input is readable'
input is readable
$ find . -maxdepth 1 -type f -name '[0-9]*' -printf '%f\n' | sort

3. Add a prefix for repeatable or automated runs

Pass --prefix when packet files need to be recognisable beside other runs. The value is prepended to each generated filename:

$ mkdir -p /path/to/second-run
$ cd /path/to/second-run
$ gpgsplit --prefix inspected- /path/to/message.pgp
$ find . -maxdepth 1 -type f -printf '%f\n' | sort
inspected-000001-006.public_key
inspected-000002-013.user_id
inspected-000003-002.sig

The prefix is text, not a directory option. If you want the output in another directory, change into that directory first. A trailing slash is not a substitute for creating and selecting the destination directory.

For a batch job, use a newly created directory per input and preserve the input separately. That makes recovery simple: an incomplete packet set can be discarded without touching the source message or a previous successful run.

4. Inspect without creating packet files

Use --no-split when you need the packet stream on standard output. It parses the input but does not write the individual packet files:

$ gpgsplit --no-split /path/to/message.pgp > /path/to/message-copy.pgp
$ cmp /path/to/message.pgp /path/to/message-copy.pgp
$ printf '%s\n' 'packet stream preserved'
packet stream preserved

This is useful for a pipeline or a controlled round-trip check. The shell redirection creates or truncates the destination before gpgsplit runs, so choose a new filename or use a temporary destination. If the command fails, inspect the temporary file before replacing anything useful.

The same mode accepts standard input. This is also how to split a stream without naming an input file:

$ gpgsplit --no-split < /path/to/message.pgp > /path/to/message-copy.pgp
$ cmp /path/to/message.pgp /path/to/message-copy.pgp

Do not feed ordinary text, a log file or an unrelated binary to the command. Errors such as invalid CTB mean the bytes at that point do not form a valid OpenPGP packet header for this parser.

5. Use verbose output when names are not enough

Add --verbose to see each output filename as it is written:

$ gpgsplit --verbose --prefix inspected- /path/to/message.pgp
gpgsplit: writing 'inspected-000001-006.public_key'
gpgsplit: writing 'inspected-000002-013.user_id'
gpgsplit: writing 'inspected-000003-002.sig'

The packet files are the useful result; verbose output is a progress record, not a machine-readable packet inventory. If a script needs to classify packets, parse the filenames only after accounting for the input and GnuPG version in use.

6. Decompress a compressed packet or convert a secret key packet

Use --uncompress when you want a compressed packet expanded as it is written. On the installed version, the resulting file uses an .uncompressed suffix. This changes the representation of the output packet, not the source message:

$ mkdir -p /path/to/uncompressed-output
$ cd /path/to/uncompressed-output
$ gpgsplit --uncompress /path/to/message.pgp
$ find . -maxdepth 1 -type f -name '*uncompressed' -printf '%f\n'

Only use this option when you have a reason to inspect the uncompressed data. Keep the original input, because decompression is an analysis output and is not a replacement for the signed or encrypted message.

--secret-to-public converts secret-key packets to public-key packets in the output. Treat this as a security-sensitive transformation: the output is suitable for public-key inspection, but it must not be treated as a private-key backup or a way to recover secret key material. Work from a copy when handling a private key and protect the output directory according to the sensitivity of the surrounding packet data.

Common failure checks

If no files are produced, check the input path, read permission and current directory first:

$ ls -l /path/to/message.pgp
$ pwd
$ test -r /path/to/message.pgp && printf '%s\n' 'input can be read'

If the input is armoured, do not mistake its visible headers for packet bytes. If the command reports an invalid packet header, stop and confirm the format rather than trying random options. If packet output is incomplete, retain the source and rerun in a fresh destination so old files cannot be mistaken for new ones. A successful exit status tells you the split completed; it does not validate a message's signature, trust, encryption or application-level meaning. Use GnuPG's verification or decryption commands separately for those questions.

Done means

  • gpgsplit --version identifies the installed GnuPG release.
  • The original OpenPGP input is preserved and remains readable.
  • Packet files were written in a dedicated directory with expected sequence and type names.
  • --prefix, --no-split, --uncompress and --secret-to-public were used only for their specific output behaviour.
  • A failed or interrupted run can be discarded without deleting the source or a previous result.