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 "/usr/local/bin/gpgconf"
 $ gpg    : chr "/usr/local/Cellar/gnupg/2.2.12/bin/gpg"
 $ version:Class 'numeric_version'  hidden list of 1
  ..$ : int [1:3] 2 2 12
 $ home   : chr "/Users/jeroen/.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.12
libgcrypt 1.8.4
Copyright (C) 2018 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: /Users/jeroen/.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] "B3476E07CF648710"
gpg_list_keys()
                id  name           email
1 B3476E07CF648710 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 B3476E07CF648710          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 B3476E07CF648710 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        183          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  9C19DB3C039ACDF0 2014-01-07 01:15:13                                FALSE
8  1777288D64D0EEB6 2014-03-12 09:17:31                                FALSE
9  B30B28D729AEFC28 2014-04-26 05:08:37                                FALSE
10 37908B4CF343E5FC 2014-11-01 18:39:25                                FALSE
11 1EB69819D7877A20 2015-11-02 07:07:28                                FALSE
12 3955E1A812646DD4 2015-11-14 19:14:18                                FALSE
13 94D5E8FA467094BC 2017-02-08 22:58:19                                FALSE
14 2D79DF2BB6E28B6D 2018-03-31 01:37:43                                FALSE
15 31CC32CEF78F3EE4 2013-08-29 13:37:52                                FALSE
16 8E549D02234CC324 2013-10-03 09:36:24                                FALSE
17 BD834C53D73E3D29 2015-01-30 22:34:26                                FALSE
18 6ED515FB1B282E9A 2015-01-30 22:35:03                                FALSE
19 22EEE0488086060F 2014-10-30 22:58:00                                FALSE
20 72B93490AFB5BB0D 2014-07-22 05:25:48                                FALSE
 [ reached 'max' / getOption("max.print") -- omitted 166 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-----

mQENBFwzwmkBCADOKcGzWXXhC9YqZvlNt7rZOKidREuiYNbdDOy8kcavkPV09KT8
VhpKl4G46kN4fyjDir7QiUu3rOd+5fMbR7HRA6NhDxO/UVw+p7TVHHGpcDkm8e3O
f4pRrK5T8imtaT80uA8kR31GyRaCe3EJe5wAjNXs52d0tOe7HHWADWdDjhvMmTOt
4ZxuBKg7kgkdzwt8X17gkeJ0NkklRlFuoZ60Oo0FfcS2/6qFaYs6ijM1LumJ0D3q
kaPytHU5HPMKtC22RzM3PhlOFmH4NlkP80D8p1gUpiZbvEiEhF6uEDX6uE9idYhP
TXY6vx0fEfYxV5G9PDeD6U6P8OZwuVm21ewjABEBAAG0F0plcnJ5IDxqZXJyeUBn
bWFpbC5jb20+iQFUBBMBCAA+FiEED1KxOJhahJogLEz1s0duB89khxAFAlwzwmkC
Gw8FCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQs0duB89khxAsgggA
k7lcGhhn979mdnTzHi9EhaNOXME3xvy41ja1nIM2YAd2FAiKZnT6iPjtKa2mNdLV
M1A8Xfrk63uUs33LvJsLyExoJYwhuXlaYI3hYsoL0tu0XgqgzuaoDoEAdxZf0O1l
l52sPDSWWUYfG+Er/3KKoM83kSRXfzU52BhVDu2hjvWYF1vSx/vFIefOmRvh1lvT
kVwQTMkYQNJJr60FjROz4kpJEepz2nwHD/u3lxk13a+U1Iy+Q/zTM6VQsUSE0Sv7
fFEtycEoTOD/BIBrISF/89W818VCmPxWiQDT42gDvfwQT5dzcBf+HII8hIpR3K50
t/D6hXktDbROeCEYluwGGQ==
=XjiS
-----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-----

lQOYBFwzwmkBCADOKcGzWXXhC9YqZvlNt7rZOKidREuiYNbdDOy8kcavkPV09KT8
VhpKl4G46kN4fyjDir7QiUu3rOd+5fMbR7HRA6NhDxO/UVw+p7TVHHGpcDkm8e3O
f4pRrK5T8imtaT80uA8kR31GyRaCe3EJe5wAjNXs52d0tOe7HHWADWdDjhvMmTOt
4ZxuBKg7kgkdzwt8X17gkeJ0NkklRlFuoZ60Oo0FfcS2/6qFaYs6ijM1LumJ0D3q
kaPytHU5HPMKtC22RzM3PhlOFmH4NlkP80D8p1gUpiZbvEiEhF6uEDX6uE9idYhP
TXY6vx0fEfYxV5G9PDeD6U6P8OZwuVm21ewjABEBAAEAB/0TOySXzPneAEios+pV
gZSrEUnz7Eb8jU6oWBL36XFAjKPDln6Su0VrPS7F8l77goEURyuoMDvL6mkTFp19
fKFC/1/iJzyPACaRVvuGAEfp/PntKWwmyGboBNT40ldo7Fm6WouvCqwjn5EQouCB
zfIDax/EIDcvqnW4p92eEEytqbelb1T2/SxL0jh7D4uvhNpcmWOxcEsWWTwhtn8s
slZJ+4sTAw5rCu5ACJyQc3EhdTpt69RavoMYJb22ObfKpHnYl20wXzB2imsE3COO
OjriiRl7KSHY8uJWs0boL8or1aY2299iTw+Pldo5Wn0ve6L/kzHRTT7avawpQxbz
LNzhBADYHNaIbOhV3QvDUAjgbB3CexQmKD4hPK5R5m/wi9yC+cKkLKkRKrHkLzQM
VyeslCgpr1LczmBBjRO521OKE4hkaM9xoCUfcRnfnQeKMVgP6UZqL0Mu9FphJtKi
ySY8K/P3aw7Yqb9tEEebgqotNTJ5APlKeFyo4jSsSKKxdC93rQQA9DbPd1eqIfQH
SWyDA4w0h0+jwy6j927Zb451ab3M2x1iwoyjuw26GEn5HSJBA9PZMYMDu58PXDMe
ZIuminNyZW0g3AIdr93CUgix8gB6ibVauyG+4hmE1HvG8IMz6cyKhnR+fT+qqAPh
y3UDLVkhXQ2+UTDiyvn7ltSJOGKmrQ8D+wRgT93DB/mp+WDORKr4/vWeMLQXkAuU
r4mlnc0H9YiF1KXjn1Mz/6okf5fMO+5r2+TPLsqiWnRAyybwkHSwzAyy7Mnx6pwF
nVZXTyF8T6//yQ1xvRbxkNp/OxCtN2RsW0Ba/Y66U27eDLYeu9vHCacpxTteZm0g
fPwt694smfcyPf20F0plcnJ5IDxqZXJyeUBnbWFpbC5jb20+iQFUBBMBCAA+FiEE
D1KxOJhahJogLEz1s0duB89khxAFAlwzwmkCGw8FCQPCZwAFCwkIBwIGFQoJCAsC
BBYCAwECHgECF4AACgkQs0duB89khxAsgggAk7lcGhhn979mdnTzHi9EhaNOXME3
xvy41ja1nIM2YAd2FAiKZnT6iPjtKa2mNdLVM1A8Xfrk63uUs33LvJsLyExoJYwh
uXlaYI3hYsoL0tu0XgqgzuaoDoEAdxZf0O1ll52sPDSWWUYfG+Er/3KKoM83kSRX
fzU52BhVDu2hjvWYF1vSx/vFIefOmRvh1lvTkVwQTMkYQNJJr60FjROz4kpJEepz
2nwHD/u3lxk13a+U1Iy+Q/zTM6VQsUSE0Sv7fFEtycEoTOD/BIBrISF/89W818VC
mPxWiQDT42gDvfwQT5dzcBf+HII8hIpR3K50t/D6hXktDbROeCEYluwGGQ==
=LIqS
-----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 B3476E07CF648710          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-----

iQEzBAABCAAdFiEED1KxOJhahJogLEz1s0duB89khxAFAlwzwmoACgkQs0duB89k
hxCnqQf9H9JokHM0JQeOS44+f4gfOd0HCAvGkbcPTTzGZRaV6wBz0cHNAW7K4GbU
ExM/qNwGSYDhRYKZNWqvcjVnXC5WD4GZf5SkHkrWZSGGcueNwOgBddBXbvV5zVxe
0vR6s7cipqcQYGFdOgSc5CRHrJIfvB1Qw6iV29RVwXH86+lXAzj5GTAnET3mc64Y
OiLGJFsdjcioeyP5asnBSCDo3GvMtKPRoR1+N2viHegLJfncBUfhKUORgPBwXdJa
FfuWCD1mh4JboK8YK+wHZIns7RG73CjPP0u1pSUh4Dt/T5A0EzUooi66pbfjrS79
d44tKCbtWQbZdNpZ1j93uTpOHx9pLQ==
=ph8u
-----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-----

iQEzBAEBCAAdFiEED1KxOJhahJogLEz1s0duB89khxAFAlwzwmoACgkQs0duB89k
hxCGPwgAljtD8d3beJQlbFQVmsyK6ZgErKYKbta9NiaK7EZQ0u5Ap0kw3DPQi8ZX
5qOghTefI5xjJJC5zhFifF6zqE1k/FkxKvPeYkeduxT+ob3EZljFFJEtbzo9/OGH
sHvbeM2cfi8ao5+d/VgV7617S40JdHSfiejQ++Oc1ZLTZLhKnOvh5rNCLkjoEEuB
QDRHPDcAkGFXcMZ1eD9/tYT02zPAmZDel8DIL/96JsrcfG1Rbpxb025g+j0EEnWX
2lKpdw6MzKjJg7s2nIZodJ3HcDoNBNH0w5tcEU8GgbTfEKGyVsm1ZAtgcbRQdgs+
Ha2MigIcfVU5qK215ZJvdxGrd9t5Ag==
=pMjW
-----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 0F52B138985A849A202C4CF5B3476E07CF648710 2019-01-07 22:19:38 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 0F52B138985A849A202C4CF5B3476E07CF648710 2019-01-07 22:19:38 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) 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 <- "6212B7B7931C4BB16280BA1306F90DE5381BA480"
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 2F0F4E14F649AF90 2007-02-15 12:06:05                                       FALSE
2 EF7CDA710BAEFEE5 2010-02-24 18:55:22                                       FALSE
3 06F90DE5381BA480 2007-02-15 09:13:25 Johannes Ranke jranke@uni-bremen.de    TRUE

Now lets verify the release files:

# Verify the file
library(curl)
curl_download('https://cran.r-project.org/bin/linux/debian/jessie-cran3/Release', 'Release')
curl_download('https://cran.r-project.org/bin/linux/debian/jessie-cran3/Release.gpg', 'Release.gpg')
gpg_verify('Release.gpg', 'Release')
                               fingerprint           timestamp hash pubkey success
1 6212B7B7931C4BB16280BA1306F90DE5381BA480 2017-05-12 17:18:43 SHA1    DSA    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/mdnc2saAQgAhSEqRpqdcYjlqrreeLpW2PXNXXh2mR26vq8/DxL4mqka
koNN+cVmPD3/3j75a6QqTumHh3ZAiPj+APxWPm3o+PAQXChEP6oV8BUexWA2Uisc
edY8zXWVS3V/4Dk7r3h85Rzfc3KodszIGC2FH8vKEs9ZYURP6f8GtAEtdcOQ2Ntq
cgj4E5Mdzl+G3siNJbYGAKQ65CuNZTPQmliKGBNjf9FK0l9Z2OmgYKGzhVPKnv4K
N/xeE2rP84EFi15ax+mcmfbnQ0iTF73jEaL/f92XBmBj6kD7KPnT0R9TxLv1nZsH
2iXDLcO5WvEhRpjcOuq69fgQYof+j1r5Ouyl6IC7rNJaAUQ2JoCY3/n/2/C6i5rd
GhWvLMOn4n1bOfSA54AhXNN4aamLpmgRjvJY9NrELyJNtRltb/9UNK6ubcAmKpqK
iS3mZRHSM+H6f73piA/Dko5kwHW0u3MhgR7/
=BqZW
-----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-----

hQEMA7NHbgfPZIcQAQf9EJpqANQXKPybA55s7iHDyws+ncVd0H+YztxQGMZbLza1
7MsNL636Q/Z+WHhmCLXeWYuaqtgAKNl3BT99LSlVzHUNBiW/6faR02Sb3PTCPBhb
uA1z0eboJGkd/78L/rQuuPeowXJrIOidus1OVwz+fKS/ShRNwSydmKFRFpNW9kVz
HlJgUaYYPExV/fFgh/A5xRwHgKmQ/dLanxEK0H/l2HXpzvB/0oDiW5hm2ATVEnLw
di1TES7I/ZQxAkO0rd1xokSkYP1EsLqh7zepe8cbBih2Tq4aSc+byK0v8MLlFruX
umdKPB99U3fYw69iG2k0Dm8xaILX2+coFIvzDcjpz9JJATjuWh8fbW5FS8ybuiMx
UfK9PC6baXr9BtOPVK5Pq9a8YMfWj7j46EfYCT3ohTB7QnzYp1s8ZvgoQv5yXJpz
LJITW9T2oIgZNg==
=XKeF
-----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!\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/mdnc2saAQf/Y7kA4oCs4YMeqnwNa5C3QiwUXGgoQ8pDvcz56G0sIYXf
w0oQSA0dr420fz1tGzhlDZDCn5P8IDIydZcF1H2nAeYmHhfEjYKB3AnuBrP5UBsu
HT7+NrSQg5on18drvSfWAWykXsouA+xklPgNWt4urwFwLJ1sY3sJ9bk4hLpmOqZe
XRp3DX2F/jV7aqcpHjL3unrgr48pTtH4S1geW9yQEiOEVc23Ver9i2czANduUqh2
XLBdB9wKS6WWENyT/JmHmikKiCzj0kgDayHLlvcsn4KwURgUmpxXLBYO8xDXVadL
rvNWLDwcpKJWXnpqf+eY04yjM1qiw7jTXAuYohMi9dLA0AFx8lANT3aVJKHLdwAL
iOmqGw7cLYu1SwmD2SpqUuVVRU/NyuFmYRrbjWTQAg6wzC15z50l57pGcWec1gW1
/KMPwyEHMKYduYf8IMJqMEFWduvdcXgen39QXs6BEmBDFKNQqENX1jKnTyX+6xw7
WfW2FbZoWs52tJQWjoeUD9JG7Fst1t5gE9r2DC95uqcLYeXFT1IMYYNk3ans4oSH
kh6IK+2iV8chLSfZHZJ/scocknM9kdLQSfAqTGGLnKC00c7fyk7lO1mPEz+8GBRZ
MTEFrjpkFkfuOGsl/f9tMc0J/06GZ3St0jgJAzwYpxTLD4s+037RT6oT+l7caA/M
EW0G2Yr8HpTK0AbEIVLy/UGw/3ljudAuWv9rmClfwepTxIDs4J+24ujUGRlfg5d+
DQJZ2PXhfJdzaHa1D0ZZzSsXRS6plTTj2SMY6nlezdvydCr8KA0qaFkzlqSSCeIO
52dMTuHrv+/RhcqoPG4mNoWmVaX+sIb4W+5S2lE72UoI2cIeDNPrqZSnTxOuyKjf
U3I=
=b0lk
-----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!\n"
attr(,"signer")
[1] "0F52B138985A849A202C4CF5B3476E07CF648710"

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