How to use GPG as a security researcher


A few weeks back, I wrote an article about why writing exploits for vulnerabilities you find in APIs is important. Several community members contacted me through emails, Slack, and Discord messages with varying questions about my comments on digitally signing reports and encrypting exploits to ensure they didn’t fall into the wrong hands.

It’s clear that some security researchers don’t know how to use public-key cryptography. I hope to change that with this article.

By the end, you will understand how to protect sensitive data and easily encrypt messages that can only be accepted by the intended recipient, preventing other parties from weaponizing your findings.

Let’s get to it!

What is GPG and why is it important for security researchers

GNU Privacy Guard, better known as GnuPG or just GPG, is an implementation of public key cryptography. This allows you to securely transmit information between parties that can be used to ensure the information is genuine and only accessible by authorized parties.

GPG relies on the OpenPGP standard (RFC-4880), an open-source implementation of Phil Zimmermann’s work with Pretty Good Privacy (PGP). GPG can provide digital encryption, signing, and key exchange and is interoperable with modern versions of PGP.

And here lies the first bit of confusion.

The inverted acronym of PGP vs. GPG leads some people to believe they are the same thing. But they are not. PGP has a long checkered history as it has changed hands with different commercial entities over the years. I think last I heard, it’s called Symantec Encryption Desktop, but it’s owned by Broadcom because they own the controlling stake in Symantec’s enterprise security business.

Whatever it’s called… just stick with using GPG. You will find installable packages for pretty much every platform you will use, is available for free, and integrates well with hardware smartcards and Yubikeys.

Why GPG is important

So GNU Privacy Guard provides a complete key management system for you that you will learn to love (or love to hate). It’s an essential but necessary evil.

As a security researcher, you will converse with many security triage teams throughout your career. You will use GPG to manage all the public keys for the security teams you regularly communicate with.

You will leverage those gpg keys to ensure that your conversations are protected and that all parties maintain situational awareness around any vulnerability disclosures and exploit code exchanges that occur.

The last thing you want is someone on the other side accidentally double-clicking an exploit and detonating it in an uncontrolled environment. Or forwarding an unencrypted message and leaking a disclosure to the wrong people within an organization.

Trust me, it happens.

Setting up GPG on your system

GPG is incredibly easy to install and set up on most systems. It’s a free download, so you can head to their website and follow the directions for your OS.

Note: Many Linux distributions already have GnuPG installed. To ensure you have the latest compatible version (GPG v2.x), check with gpg --version.

Below is a quick cheat sheet to install GPG to several operating systems using a command prompt or shell.

Ubuntu and Debian-based Linux distros

sudo apt-get install gnupg


sudo yum install gnupg2


You can install the GPG Suite for MacOS, but I prefer package management with Homebrew:

brew install gnupg

Windows 11

winget install -e --id GnuPG.Gpg4win

This will also work with Windows 10 if you have App Installer installed from the Microsoft Store. Read here for more details.

Generating your key pair for signing and encryption

Once the software is installed on your OS, you must create your own GPG keys. Before we do that though, we need to discuss what kind to generate.

Since around 2021, GPG now supports default keys for ECC (Elliptic Curve Cryptography). ECC is more efficient as you get an equivalent cryptographic strength with significantly smaller key sizes. However, it comes at a cost… there is far more support for RSA keys across different operating systems.

If you plan to use Yubikeys, I’d recommend using ECC. The size and speed will matter there. Otherwise, use RSA to have the most compatibility.

As such, for now, you do not want to follow the guidance online to use gpg --gen-key🚫 as it may not generate the proper RSA keys you will probably want to use.

Instead, to generate your first set of keys, run the following command:

gpg --full-generate-key

When prompted, answer the questions as follows:

  1. Select the kind of key of RSA and RSA.
  2. Set the key size to 4096.
  3. Set the key to expire in 2 years (2y).
  4. Accept the expiration prompt (y)
  5. Enter your name as you want the recipients to see it. Use your real name or maybe your handle.
  6. Enter your email address.
  7. Leave the comment blank.
  8. Hit O to accept the configuration.
  9. Enter a strong secret passphrase.
  10. If prompted, move your mouse around to generate extra entropy.

When the process completes, you should be able to run gpg --list-keys to see your public key on your GPG keyring. If you want to see your secret key, type gpg --list-secret-keys.

Time to back them up.

How to securely back up your keys

GPG includes tooling to import and export keys across systems. I highly recommend you ASCII armor these so they can be easily moved around. Like any sensitive confidential text file, it’s up to you to properly handle and safeguard them.

Backing up your keys

When backing up your keys, it is good to name them appropriately so they are easy to identify. For this exercise, I will use simple naming for the examples. In a real-world export, I would recommend you be far more descriptive.

Note: When using the --armor or -a argument with the following commands GPG will output the key(s) in a PEM format.

Export all public keys: gpg --armor --export > public-keys.asc

Export a single public key: gpg --armor --export key-id > my-public-key.gpg

You can retrieve the key id using the following command: gpg --list-keys

Export all private keys: gpg --armor --export-secret-keys > private-keys.asc

Note: You will be prompted for your secret passphrase to do this.

Export trust store: gpg --export-ownertust > ownertrust.asc

Restoring your keys

gpg --import public-keys.asc
gpg --import private-keys.asc
gpg --import-ownertrust ownertrust.asc

Getting a vendor’s public key

Now that you have created your own keys and backed them up properly, it’s time to find the public keys of those people you want to converse with securely.

There are many ways to find them. You can use public key servers like or get the recipient’s public key directly from the other party by asking.

As you are doing security research, chances are the vendor will publish their public key somewhere findable, like on their website or within its Vulnerability Disclosure Policy (VDP). Have you ever heard about security.txt? It’s a proposed standard that allows websites to define security policies in a well-known and established manner through a text file. It’s now an RFC standard (RFC 9116).

You can usually find this file in an app directory at <domain>/.well-known/security.txt or at the root of the domain at <domain>/security.txt.

For example, if you are a bug hunter working with the Google Security Team, you can find theirs at, pointing you to their public key here.

You can take that corresponding public key file and download it locally. Then you can import it using a command like gpg --import publickey.txt . In this case, you will end up importing one for and one for

Importing keys doesn’t immediately trust them. A key’s trust level is something that you alone assign to the key and is considered private information. In fact, it’s not even stored with the key in case you ever export it. This is what the ownertrust database is for.

If you want to trust a key, you can edit it and assign a trust level. Try this:

gpg --edit-key

# In the interactive GPG prompt
gpg> trust
Your decision? 4
gpg> save

OK, so now you have the recipient’s public key imported and trusted in your keyring. Let’s start using it!

Using GPG to sign and encrypt your vulnerability reports and PoC exploits

Now that we have all the necessary keys in place, we can start communicating with the security triage team. Many email clients have plugins and extensions that can be used to help with this, but I am going to show you how to do it manually.

The main reason is that if you use modern web clients like GMail,, or Office 365… these extensions don’t work. And many browser extensions that try to compensate for this are flaky at best.

I will show you several scenarios, from encrypting files, signing exploits, and verifying messages.

Encrypting and Signing a Vulnerability Report

Let’s say you want to submit your report to the Google security triage team. You’ve downloaded, imported, and trusted their public key and now want to send them your sensitive report that you’ve written in markdown.

You could do something like this to encrypt files:

gpg --sign --encrypt --armor -r

This would then produce, an ASCII armored PGP encrypted message file that you could attach to any email. The contents would look something like this:



Personally, I get lazy at the command line and would use the shortened version of that command which looks like this:

gpg -sea -r

You can use gpg --help to see other options you might want to consider. As an example, if your original report name included sensitive metadata you would want to redact, you could rename the output using -o:

gpg -sea -r -o

How to decrypt messages from the security triage team

As you engage with the security triage team, they may have sensitive communications, information, or files that they will share with you. These will be encrypted with their private key and your public key to ensure only you can open them.

When they send you encrypted messages and/or files you can quickly decrypt them using the following gpg command:

gpg -d -o filename.msg filename.msg.asc

You will be prompted to enter passphrase before you can decrypt files.

If you don’t include the -o option during decryption, it will dump the contents to stdout.

Signing an Exploit

So when sending exploits to the security triage team, you could (and should) consider following the previous guidance on signing, encrypting, and ASCII armoring the file(s). If you have multiple files, you might consider archiving/zipping up all the original files and then using GPG against that entire archive file instead.

But you might come across times when you are directly communicating with the triage team and/or developers who may be unable to decrypt something you send. I’ve had occasions where I was having real-time communications with developers where the comm channel was secure, but I wanted to make sure what they got from me wasn’t altered during transmission.

This is where GPG’s –clear-sign param comes into play. You can use the following command:

gpg --clear-sign

This would generate a PGP signed message in which the exploit is still in plaintext but signed by me. It’s also defanged enough that someone can’t execute it without removing the PGP artifacts around the exploit.

It might look something like this:

Hash: SHA256

#!/bin/env python3

# Some exploit code goes here


On their end, they can verify that the exploit hasn’t been tampered with by importing your public key to their GPG keyring and then running the gpg command gpg --verify

If they want to view the file’s contents without the signature, they can use gpg -d >

Kinda simple, huh?

Closing Thoughts

Every security researcher should get familiar with GNU Privacy Guard (GPG). Knowing how GPG works is invaluable for securely sending vulnerability findings, exploits, or other sensitive information over the internet to those you will be working with.

Hopefully, I’ve given you the foundation to encrypt files, verify signatures, and decrypt messages. Once you get comfortable with GPG encryption, you’ll find it’s a powerful tool in your arsenal.

Found this useful? Keep up with my work by subscribing to my free weekly newsletter, where I share exclusive tips, tricks, and killer command line cheats to hack your apps and infrastructure.

Dana Epp