DISCLAIMER: Author is not an expert in cryptography (he is not an expert in anything really). Use this stuff at your own risk. If you find bugs or inaccuracies, please create an issue or PR on the github repository.

GPG basics

The GNU Privacy Guard, also known as GnuPG or simply GPG, is a popular open source OpenPGP (RFC4880) implementation. The system is widely trusted for securing integrity and confidentiality of internet communications through various cryptographic methods. GPG is used in Debian and Redhat to verify downloads from package managers (apt, yum) and people like Edward Snowden and Glenn Greenwald use it to encrypt confidential emails.

Public key crypto

Like most modern crypto systems, GPG makes use of public key methods. You can easily generate a personal keypair which consists of a private key and corresponding public key.

pubkey

Your private key is to be kept secret and needed to sign or decrypt messages. The corresponding public key should be made available to anyone that needs to verify your signature, or encrypt messages which can only be decrypted by you.

Once we have someone's public key, we can send them secure messages and verify their signatures. However how do we find and authenticate the public key of a person or server if we have not talked to them before?

Web of trust

The complexity in public key systems derives from authenticating public keys. If we can not trust our communication channel to be safe, we can only be sure that a public key belongs to given person if it has been signed by someone that we do trust.

The major difference between GPG and PKI systems (such as HTTPS) is how we authenticate public keys. HTTPS is based on a system with Certificate Authorities (CA). Anyone can create a keypair for any domain/personal name, however we only trust public keys which have been signed by an official CA. This CA is typically a commercial vendor which verifies your identity (e.g. via a copy of your passport) and then uses their own keypair to sign a certificate containing your public key and your personal name / email / domain.

trust

GPG uses a different system which does not distinguish between peers and authorities. In GPG, anyone can sign another persons key. The GPG user determines which peers they choose to trust in their personal keyring. For new peers, the GPG software helps you figure out which of your current peers has verified the identity of the new peer, perhaps indirectly via a third or fourth peer, and so on: a “web of trust”.

The easiest way to exchange public keys and key signatures is via a keyserver. GPG is compatible with existing PGP key servers. These servers mirror each other so most keys are available on either one. This package automatically retrieves keys and signatures via the gpg_recv function.

GPG keyservers do not need HTTPS. One should only trust GPG keys on basis of GPG signatures, regardless of how they were obtained. For this reason it is also valid to share GPG public keys via e.g. a website or email.

Your keyring

It is important to know which version of GPG you are running and where your home dir is. Your home directory contains your configuration and the keyrings. GPG defaults to your system keyring, which is the same as the gpg command line utility and system package manager use.

str(gpg_info())
List of 5
 $ gpgconf: chr "C:\\Program Files (x86)\\GnuPG\\bin\\gpgconf.exe"
 $ gpg    : chr "C:\\Program Files (x86)\\GnuPG\\bin\\gpg.exe"
 $ version:Class 'numeric_version'  hidden list of 1
  ..$ : int [1:3] 2 2 19
 $ home   : chr "C:\\Users\\tomas\\AppData\\Roaming\\gnupg"
 $ gpgme  :Class 'numeric_version'  hidden list of 1
  ..$ : int [1:3] 1 12 0

Use gpg_restart to switch to another home directory, e.g. for a client which uses its own configuration and keyrings. For this example we store keys in a temporary directory.

gpg_restart(home = tempdir())
gpg (GnuPG) 2.2.19
libgcrypt 1.8.5
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: C:/Users/tomas/AppData/Roaming/gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

Use gpg_list_keys() to see the current contents of your keyring. It is empty to start with:

gpg_list_keys()
[1] id    name  email
<0 rows> (or 0-length row.names)

Generate keys

Use gpg_keygen() to generate a new public private keypair:

(mykey <- gpg_keygen(name = "Jerry", email = "jerry@gmail.com"))
[1] "5117FBA456CCF559"
gpg_list_keys()
                id  name           email
1 5117FBA456CCF559 Jerry jerry@gmail.com

Import from keyserver

Use the gpg_recv function to download a given key and all available signatures for this key from a keyserver. For example let's import the public key from Michael Rutter which is used to sign the Ubuntu r-base packages from CRAN:

gpg_recv(id ="51716619E084DAB9")
Searching: https://keyserver.ubuntu.com
     found   imported    secrets signatures    revoked 
         1          1          0          0          0 
(keyring <- gpg_list_keys())
                id           name              email
1 5117FBA456CCF559          Jerry    jerry@gmail.com
2 51716619E084DAB9 Michael Rutter marutter@gmail.com

Note that for imported keys, we do not have the private key:

(secring <- gpg_list_keys(secret = TRUE))
                id  name           email
1 5117FBA456CCF559 Jerry jerry@gmail.com

Import from file

The gpg_import function reads an armored GPG key from a file or URL:

gpg_import("https://stallman.org/rms-pubkey.txt")
     found   imported    secrets signatures    revoked 
         1          1          0          0          0 

However this file does not contain any signatures for this key. If we import it from a keyserver we also get the signatures:

(rms_id <- gpg_list_keys("rms")$id)
[1] "2C6464AF2A8E4C02"
gpg_recv(rms_id)
Searching: https://keyserver.ubuntu.com
     found   imported    secrets signatures    revoked 
         1          0          0        199          0 
gpg_list_signatures(rms_id)
                 id           timestamp             name       email success
1  2C6464AF2A8E4C02 2013-07-20 18:32:38 Richard Stallman rms@gnu.org    TRUE
2  624DC565135EA668 2013-07-20 18:37:45                                FALSE
3  F05DDAE40371FCE5 2013-09-15 23:18:46                                FALSE
4  231696C3EAE0078A 2013-09-24 23:15:58                                FALSE
5  7B585B30807C2A87 2013-09-28 22:59:04                                FALSE
6  7CEF29847562C516 2013-09-29 04:59:53                                FALSE
7  520E0C8369B003EF 2013-08-20 12:31:55                                FALSE
8  D56E1B4C135D47A1 2013-08-29 13:36:03                                FALSE
9  31CC32CEF78F3EE4 2013-08-29 13:37:52                                FALSE
10 9439E86389D0AF41 2013-08-29 13:55:01                                FALSE
11 C5CFD08B22247CDF 2013-09-24 15:00:05                                FALSE
12 20B7283AFE254C69 2013-09-28 22:44:02                                FALSE
13 A866D7CCAE087291 2013-09-29 17:59:25                                FALSE
14 6D33FBF5B5E4C71A 2013-09-30 15:52:36                                FALSE
15 8916CADF8ACD372A 2013-10-02 13:17:17                                FALSE
16 8E549D02234CC324 2013-10-03 09:36:24                                FALSE
17 D605848ED7E69871 2013-10-04 11:03:23                                FALSE
18 758EAEC123F62336 2013-10-13 00:53:08                                FALSE
19 7B585B30807C2A87 2013-10-18 21:27:08                                FALSE
20 E4A6D8A25310523C 2013-10-23 02:53:11                                FALSE
 [ reached 'max' / getOption("max.print") -- omitted 90 rows ]

The signature only contains the key ID of the signer. You would need to download the corresponding pubkeys to actually verify these signatures.

Export a key

To export our newly created public key:

str <- gpg_export(id = mykey)
cat(str)
-----BEGIN PGP PUBLIC KEY BLOCK-----

mQENBF78YDwBCADUPpVDIaT5iZgdK3hsiBUrO+gDqvOp6erQyuNjePUxxOKpBJgy
dkfu9xpBvhAoHVGim3BJrmHTFx6dlYrSgigmdOCmLgU9IiSGdUd72L3ruaJDyHM0
iYbcSksFbMYEIMtFCZo/UlqDkd01kWAHFD0Yl+1w/J4XtaP1AvqL9lFglSn5Met2
zWIgNuZEuywW/CGYQTR4a9Ry/THH046QAVZsGDhYZTJZAdqUeMTS22wWrR5zSVS9
oNjNOnArOTsWXvnboYF3xtXcffmrpM+ZVJk8QfI0AY0urNT1CCqAs+6EzRTHEYWC
Zin7/Rfu65gdwXd7BNzSwpVwQj7wDadEN77fABEBAAG0F0plcnJ5IDxqZXJyeUBn
bWFpbC5jb20+iQFUBBMBCAA+FiEEeg7aOdgQGeh2MRt4URf7pFbM9VkFAl78YDwC
Gw8FCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQURf7pFbM9VmZbgf9
F0yew+bSjba4oFUqyjV+R6Ylu9dpTdjKeaPrpdUZpJuQXV47bzknTDku8Jb4+/Nu
em4gaaHMOCE79bGLmkOEJTl3C8o9ha4aNDGhqgclo8TZG3FB2DiTtP9fHNOD3B8V
wAIYaa7AqoH5iDES8aBYX0OqIJncBrv2uN0bfoc+T5dS2jjC6TFxdWQgrlA6Siyf
Zuuqmas0mEOC8ONOGtD7ZI8rdY4C+TM2hjxpTsFNbZ5lDyI16RwA0YSqDGz4aIJB
Hyj2bNdwVuV5ihLBMiHmp4Vzx6D3JHn7V03EgwNO86lxggi5WVmoykv3jtYSnTmY
nNDu0b4oQ8xLee85bQdMEQ==
=HN36
-----END PGP PUBLIC KEY BLOCK-----

If you also own the private key you can export this as well:

str <- gpg_export(id = mykey, secret = TRUE)
cat(str)
-----BEGIN PGP PRIVATE KEY BLOCK-----

lQOYBF78YDwBCADUPpVDIaT5iZgdK3hsiBUrO+gDqvOp6erQyuNjePUxxOKpBJgy
dkfu9xpBvhAoHVGim3BJrmHTFx6dlYrSgigmdOCmLgU9IiSGdUd72L3ruaJDyHM0
iYbcSksFbMYEIMtFCZo/UlqDkd01kWAHFD0Yl+1w/J4XtaP1AvqL9lFglSn5Met2
zWIgNuZEuywW/CGYQTR4a9Ry/THH046QAVZsGDhYZTJZAdqUeMTS22wWrR5zSVS9
oNjNOnArOTsWXvnboYF3xtXcffmrpM+ZVJk8QfI0AY0urNT1CCqAs+6EzRTHEYWC
Zin7/Rfu65gdwXd7BNzSwpVwQj7wDadEN77fABEBAAEAB/44+wZCjBVI4w5CAool
hRE91qru1SXuf3zJijaq3W3iayu42aFspsGgH5nefYLD6j8g6x8lwNnFfKb9AolP
A59415b6Nk+0vmZU7MaAsssmLmOoU/fN6oAYwx9J+Q5eTFmWEsJk7pybRv0+5OUF
cYMHh744v7FHxz2ZyS9vhPUK+vOev+nQEw81BMWrv0EC31F4AsihBiPrOtId4Qqk
4ll//oP/vp6nW8hU3VMCp+ysSMKfF707/pIjy1eAWuHKJ4ZAQkhGUlPi5SBqLF7M
SUyECdh0Xq/HzoBXfdBp0xSohk8vddRon+MlEV90Lx0cMNkd5qxbbZwHGeOh2G9Q
dNDNBADiKE7JFxjZuSTFhVVhwpwjezwW2CczYzXPVL55QRZZXhooa3wJSAzD6vXW
xRp2PH64yOxjPT600sBwnhQQTciusQpx1dMQSWd4sU1INfBbgRTitqJNzQL2Mnlr
MiKHtvMKjrE8M/yesQzG6fAt1irsA+nNkspF6asYSg3p3qzjGwQA8EBJ8ZSh+F77
N1fw4Ji2JxxIEqLl0JzpDjWbNktRH7jpO+YmjGCpyEADr0ctIKfENmx74u7876El
p6UH3H8px/UlvsMf726CTrt9MSQN0wQ7zL0MT3WXzAFRF9Hf4nDzT2qFwSfDXzT1
8JLuUN0XBitIC17uz2U2xLOhoMr9i40D/1CI3FeQDhTo5jaztgD1e87AtvDSfJP7
rU+I0CeQug3BKJodV47uHgq0poJI14/5vrlxf19JAgFeLZLmNGJkgciBULFxcTon
q1zXviRpRvMC7vCnb8OBvke96Fw+d1F0fR+skyRZ23rYgQFbR58/4dg5ucsMUSFh
7P4+jp456L2zRPS0F0plcnJ5IDxqZXJyeUBnbWFpbC5jb20+iQFUBBMBCAA+FiEE
eg7aOdgQGeh2MRt4URf7pFbM9VkFAl78YDwCGw8FCQPCZwAFCwkIBwIGFQoJCAsC
BBYCAwECHgECF4AACgkQURf7pFbM9VmZbgf9F0yew+bSjba4oFUqyjV+R6Ylu9dp
TdjKeaPrpdUZpJuQXV47bzknTDku8Jb4+/Nuem4gaaHMOCE79bGLmkOEJTl3C8o9
ha4aNDGhqgclo8TZG3FB2DiTtP9fHNOD3B8VwAIYaa7AqoH5iDES8aBYX0OqIJnc
Brv2uN0bfoc+T5dS2jjC6TFxdWQgrlA6SiyfZuuqmas0mEOC8ONOGtD7ZI8rdY4C
+TM2hjxpTsFNbZ5lDyI16RwA0YSqDGz4aIJBHyj2bNdwVuV5ihLBMiHmp4Vzx6D3
JHn7V03EgwNO86lxggi5WVmoykv3jtYSnTmYnNDu0b4oQ8xLee85bQdMEQ==
=Y32q
-----END PGP PRIVATE KEY BLOCK-----

Delete a key

Delete a key from its ID or fingerprint. Let's delete the RMS key:

gpg_delete('2C6464AF2A8E4C02')
[1] "2C6464AF2A8E4C02"
gpg_list_keys()
                id           name              email
1 5117FBA456CCF559          Jerry    jerry@gmail.com
2 51716619E084DAB9 Michael Rutter marutter@gmail.com

Digital Signatures

A digital signature is a mathematical scheme for demonstrating the authenticity of a digital message or document. If you sign a file using your personal secret key, anyone can verify that this file has not been modified (i.e. the hash matches the one in your signature) via your public key.

GPG signatures are widely used by Linux package managers such as apt to verify the integrity of downloaded files. Typically the public key is shipped with the OS, and the private key is owned by the repository maintainers. This way we can safely install software from any mirror or network.

Sign a file

Let's use the private key we generated earlier to sign a file:

myfile <- tempfile()
writeLines("This is a signed message", con = myfile)
sig <- gpg_sign(myfile)
writeLines(sig, "sig.gpg")
cat(sig)
-----BEGIN PGP SIGNATURE-----

iQEzBAABCAAdFiEEeg7aOdgQGeh2MRt4URf7pFbM9VkFAl78YEEACgkQURf7pFbM
9VkrSQf/bYkZXzrNHY4rCcQPyc5doM7X03lBuLSkCpCtPwdau1FBQOLw0whrhJ+B
fW7gW3xSsPsEVhdVUSYc2nTLOrt/vF4rXyVRyoWUy4ivZrtDc1Zvx4zAxqecsuD4
vYFg6SYLeMPcuAp2y2zKi6Eq3eBX6ShYxWDhsNYVuDM2Jn27RPLAJN5DnA4/fiVq
ZA7/+ypOm/h6t2FUW6L721tuJ0AZXvYwNmbXaVyFhLBHOlnGJfEgiZ251c6RBjVS
1FE53Ru3uWvP7pHFSgdoW8EyK/2u23JlUfPVliCTZPAII8igcy3fymngY6EuMehz
KnKs5qYTtQVNdhB6IqwYXZLO9B5ZoQ==
=Oru1
-----END PGP SIGNATURE-----

You can also create a signed message which includes the data itself by setting mode to normal or clear, which is useful for email:

clearsig <- gpg_sign(myfile, mode = "clear")
writeLines(clearsig, "clearsig.gpg")
cat(clearsig)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

This is a signed message
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEeg7aOdgQGeh2MRt4URf7pFbM9VkFAl78YEEACgkQURf7pFbM
9VnS+wgA0UYYYbd55Xq6JJNd8o2cDiFGz/h52Adah0LrbGyeLxh+f85FC6Fcjd0r
7Yo2WqRM4kbi3uGWOkWzYl3YyZeZ6zUNdR/XRrCIGyj9nYnWkO8QvjvUTEHl20jn
UlrWGI5WpSX5ubkSENsazrZvu+98L6ArbcOSm8/k3TtsmNLBTfzq7qENiQ59TavZ
fju3hhwOGeiyPxMuVbWGPMI6/ECkKO+bD5aKtn9DkZF/W98OdZFwpvPhIVy7yu4h
JgztLx4UiuOJ3viwfbq8LkD1jcKiJ+Y+3Wt7Nceyogt5pCkSKyW8L3x5aBskFMyp
7eEjO3CJo+UlnQXbpSRqAYHtL3bXYQ==
=lefu
-----END PGP SIGNATURE-----

Verify a signature

The gpg_verify function will see if a signature is valid for any of the keys in the keyring:

gpg_verify("sig.gpg", data = myfile)
                               fingerprint           timestamp   hash pubkey success
1 7A0EDA39D81019E876311B785117FBA456CCF559 2020-07-01 12:06:57 SHA256    RSA    TRUE

If the signature is in clear or normal mode, the signature file contains both the message and signature:

gpg_verify("clearsig.gpg")
                               fingerprint           timestamp   hash pubkey success
1 7A0EDA39D81019E876311B785117FBA456CCF559 2020-07-01 12:06:57 SHA256    RSA    TRUE

Debian example

Let's verify a Debian file. The Debian page on CRAN says the following:

The Debian backports archives on CRAN are signed with the key of Johannes Ranke (CRAN Debian archive) jranke@uni-bremen.de with key fingerprint 6212 B7B7 931C 4BB1 6280 BA13 06F9 0DE5 381B A480

Let's import his key so that we can verify the Release file, which contains checksums for all files in the repository:

# take out the spaces
johannes <- "E19F5F87128899B192B1A2C2AD5F960A256A04AF"
gpg_recv(johannes)
     found   imported    secrets signatures    revoked 
         1          1          0          0          0 

If you don't trust the CRAN homepage, you could check who has signed this key. You'd need to import the corresponding peer keys for more information.

gpg_list_signatures(johannes)
                id           timestamp           name                  email success
1 AD5F960A256A04AF 2016-11-16 01:18:06 Johannes Ranke johannes.ranke@jrwb.de    TRUE
2 2F0F4E14F649AF90 2016-11-16 01:29:16                                         FALSE
3 06F90DE5381BA480 2016-11-16 01:35:39                                         FALSE

Now lets verify the release files:

# Verify the file
library(curl)
curl_download('https://cran.r-project.org/bin/linux/debian/buster-cran35/Release', 'Release')
curl_download('https://cran.r-project.org/bin/linux/debian/buster-cran35/Release.gpg','Release.gpg')
gpg_verify('Release.gpg', 'Release')
                               fingerprint           timestamp   hash pubkey success
1 AD7B5162BA456BE3526F8D92FCAE2A0E115C3D8A 2020-02-29 14:48:03 SHA512    RSA    TRUE

Looking good! We can trust the checksums in the Release file to be legitimate.

Anonymous Encryption

GPG uses public key encryption. You can use someone's public key to encrypt a message or document, in a way that only the owner of the corresponding private key will be able to decrypt. This is a great way to send somebody highly confidential data.

Encrypt a message

For example we want to send an email Jeroen containing top secret information that may not be snooped by our ISP or email provider. First we import Jeroen's public key using the ID as listed e.g. here:

jeroen <- '16C019F96112961CEB4F38B76094FC5BDA955A42'
gpg_recv(jeroen)
     found   imported    secrets signatures    revoked 
         1          1          0          0          0 
writeLines("Pizza delivery is on it's way!", "secret.txt")
msg <- gpg_encrypt("secret.txt", receiver = jeroen)
writeLines(msg, "msg.gpg")
unlink("secret.txt")
cat(msg)
-----BEGIN PGP MESSAGE-----

hQEMA4BQ/mdnc2saAQf/aK4+M7GnsoNa6KxnvH9Lcid3F/b4KpvGx70crRbH0U3T
wOzbddIKWS1prvVvZ35S9OKlqms4sADXGuPITGjm/d7dIlTbyv3IMstwT4M5YrJY
JGITB04vaer4RtllMTknECgEUPxMhqxK7qhb9VyRfihCjmiFObfoukX1cN3iFuuJ
jyaqiOOqQR5gCIchQdmVdVds/jHBJKOnpAJHnQJ/gRmrpgVa63dfIlSQQZD6CxAz
gPpWRVZPRml9YJ7pf7jW8cABl9I/T3j4HrNydqIPukP2eGiAdFpqPwwclZLO5vGz
q174HKuyt8zfs2hIEBUorpOPWINy2Y1mEI8HAoL/vdJbAS6yH7Y+Vz4eCa+W9+Ou
VaSOW7n7f5uJLBLV3qXt0KS7DGFlavOjty4jiGfZvERVJUkKFbK880/rQme+Jlli
+YK0FXHRIbhxRU8Eckc1cUVSBk5RdMBDuxkGBg==
=4u2X
-----END PGP MESSAGE-----

Now you can safely send this message over any channel (email, twitter, etc). Nobody in the world besides Jeroen will be able to decipher this message (not even you).

Decrypt a message

Decrypting a message is just as easy. GPG will automatically find the correct private key from your keyring, or raise an error if you don't have it. For example we will not be able to decrypt the message we created above for Jeroen

# This will error, we do not have this private key
gpg_decrypt("msg.gpg")
Error: GPGME verify signatures and decrypt message error: No secret key

To demonstrate decryption, we encrypt a message using our own keypair (for which we own the private key).

writeLines("This is a test!", "secret.txt")
msg <- gpg_encrypt("secret.txt", receiver = mykey)
writeLines(msg, "msg.gpg")
cat(msg)
-----BEGIN PGP MESSAGE-----

hQEMA1EX+6RWzPVZAQf/eELQ3f8TLnHOSL0F/+LAiH+fNXRoQyXQDhv8ZEAhIgaV
wtLv8KUJP9Djjz6c9chv5VMa2YbAm0tUHNP1H/+TsjCG7g+J8A2UxTX/NdqVMeI4
D0Gru5Kefwu2VJ6+JIzpPN75r2W7zGNu3/5gx2ESRojb4tKzEx933lBJ+KR8yOtO
GSV/IX72a+T+TB3Z5PzLkD6RODVxmGevBSyJhGt3ofFdVisDCcIvbD58xX5/ySOp
DdI+IZY5qqODPhLCg0HYv5uyc4G0XJw12c8+PqgnU4MRUC9B4ucivbs3WBDCfBox
4bRDHqpBYeGNfWqirnVkCP/N4u/xswLQ3mHTyg849NJKAbrUZFpU5Pb4GaXI2fdY
3AThnbKIvo/NWjZl8QxkchIT8l0dLn5XPggHecoz29ObtX4Uu4cDOui6dpAlcwFu
DpzbWb1C0/UQ5Mw=
=+s1C
-----END PGP MESSAGE-----

Decryption is simple, given that we own the secret key for the message:

gpg_decrypt("msg.gpg")
[1] "This is a test!\r\n"

Authenticated Encryption

So we showed how to encrypt a message so that it can only be read by the receiver. But how does Jeroen verify the sender identity?

Sign and Encrypt

In signed encryption, also known as authenticated encryption, uses combined encryption and signing. The public key of the receiver is used to encrypt the message, and the private key of the sender to sign the message. This way the message is both confidential and the integrity of the sender can be checked and verified, only by the receiver.

msg <- gpg_encrypt("secret.txt", receiver = jeroen, signer = mykey)
writeLines(msg, "msg.gpg")
cat(msg)
-----BEGIN PGP MESSAGE-----

hQEMA4BQ/mdnc2saAQgA1glpsVhmWZ6HUEibzzKmW4LgVx51Q1uLbjS4PrYC7j3V
EJLQrFTrSh0SuSy3gJvYB74sq39cTf3aKqhOSnN4hWkmR5zZRux2pUOcouyHmwXM
/yzHlNYVegIgUnds6iNIEREjH1wUrikrCAtGlEHT685w24l3ViMKSwcA1I5AN5zO
nhK+t8ejiia3unpJsVyxm88Dh2uAwg9YGzwKtmtGoAzsZ3GqfWbLqFwY3wHoQ6gN
f97Ssx8Sg+6o92Ovdv1o2+dsxpw5aLZBqzbzhdDkNpV8raKiCbyF4O3VA8Nt0yPi
PYll7Fo1UMSzXTkAI/fJ8XmoJUrbMcTaP13jSYLGAtLA0QFRMAldr+J/eG8Zdi+n
t71+f5kvqyp3XiiIt/Cwp0zbTs2RbTRdJW2AQagGe4sp3u7O/7m1F3RdLXFcVDHR
xPFyGn9KRiR38q00pRz1509tNzu45dyHqH8dq/jCC/ZhPic5LnlgGY7l098wago5
amG35RU0FJkGHr4IxDRJh9Yeh7pOxn5m8YIHewGt9vMXNOEn5NzbCaiD2ltRTUSS
n722WNl7xyMnq6xJhKMDlx3vNXmiU4ITKrjycASElbC2yv+HLwZBbLhrqCsRyRIX
z87g4eE1Gtw/jGVBMBC4Aj9b5+YkPsBqsek/gFUIh9BCWuXnJpw1aPWx40CP6Kq8
kvsI/02GXATNi9DtG0oPQZivwAA6lZzHjeyYLJ1q/GrH/ZhiDjnlSMOncUn1sIW1
ddX/7J5LLCB86CckoS9ur0aq+YmZtZD3/uP+1XReraMJ690tbVL0hR2MD8KpmT0Q
wdoxOqStZJ1swU7drrbzITjN5IRY3LhlAbD1lRejAnOmcAoo+UXk4SEsQ0lr/U0q
6Svs
=C/4L
-----END PGP MESSAGE-----

Decrypt and Verify

If the encrypted message contains a signature, it will automatically be verified when the message is decrypted. The function raises an error otherwise.

For purpose of illustrating authenticated decryption, we encrypt and sign using our own key (which usually does not make sense):

msg <- gpg_encrypt("secret.txt", receiver = mykey, signer = mykey)
writeLines(msg, "msg.gpg")
gpg_decrypt("msg.gpg")
[1] "This is a test!\r\n"
attr(,"signer")
[1] "7A0EDA39D81019E876311B785117FBA456CCF559"

The signer fingerprint (if any) will be added as an attribute to the decrypted message.