Recently had to generate new GPG keys. If on Windows Gpg4win or Kleopatra is recommended. Below are using GnuPG
in Ubuntu Linux to generate asymmetric keys for encryption.
sudo apt-get install gnupg
Key Generation
This will start the key-generation prompts
gpg --full-generate-key
The default is rsa3072
(previously 2048) but will be using 4096-bit key.
gpg --default-new-key-algo rsa4096 --full-generate-key
Unattended/Batch
You can also do an unintended uninstall if provided a file.
cat >key_gen_info <<EOF
%echo Generating a basic OpenPGP key
Key-Type: RSA
Key-Length: 3072
Subkey-Type: RSA
Subkey-Length: 3072
Name-Real: Wind010
Name-Comment: Example Key
Name-Email: tester@test.com
Expire-Date: 1y
Passphrase: <your_password_here>
# Do a commit here, so that we can later print "done"
%commit
%echo done
EOF
Then pass it in with --batch
flag:
gpg --batch --generate-key key_gen_info
Add some entropy by pressing the keys and moving the mouse when generating the keys:
We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy.
Because computers are deterministic the pseudorandom number generator needs some external input as a seed.
You'll get an error message if there is insufficient randomness:
Not enough random bytes available. Please do some other work to give the OS a chance to collect more entropy! (Need 210 more bytes)**
NOTE: If you cancel out of the passphrase entry stage on a prompted key generation, it may hang. You can look up the gpg-agent
process with ps aux
and kill the process id with kill -9 <gpg_agent_process_id>
.
Show/List Keys
Once the keys are generated you can list the public and private keys using the following:
gpg --list-keys
gpg --list-secret-keys
The keys can be identified with the email address provided or the unique user key.
Export Keys
I'm exporting to with --armor
for an ASCII
armored file instead of binary.
Public Key
gpg --output public.asc --armor --export [email_or_user_id]
Private Key
gpg --output private.asc --armor --export-secret-key [email_or_user_id]
Or with a passphrase provided (single quotes to avoid string interpolation/expansion):
gpg --output private.asc --armor --batch --pinentry-mode=loopback --yes --passphrase '[your_password]' --export-secret-key [email_or_user_id]
Import Key
gpg --import [your_public_or_private_key]
Encryption/Decryption
Encrypt
Use the public key to encrypt the specified file.
gpg --output [your_encrypted_filename] --encrypt --recipient [email_or_user_id] [your_unencrypted_filename]
Decrypt
If you have the private key imported the decryption occurs without specifying the private key.
gpg --output [your_unencrypted_filename] --decrypt [your_encrypted_filename]
or
gpg --output [your_unencrypted_filename] --passphrase [your passphrase]--decrypt [your_encrypted_filename]
Delete
Public Key
gpg --delete-key [email_or_user_id]
Private Key
gpg --delete-secret-key [email_or_user_id]
With no prompts include --batch --yes
as options. The --yes
is specific to private key deletion. Note that deleting the private key will not automatically delete your public key from the keyring (~/.gnupg/pubring.pbx).
Additional
If you wanted to remove all newlines from the file or replace newlines with \n
for storage in say KeyVault:
Delete
tr --delete '\n' < pub.asc
Replace
sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g' file
or with Powershell
Delete
(Get-Content -Path 'public.asc') -Join | Out-File -Path 'new_public.asc'
# OR
(GC 'public.asc') -Join > 'new_public.asc'
Replace
(Get-Content -Path '.\public_test.asc') -Join "\n"
# OR
(GC 'public.asc') -Join "\n"
To format the one-line key back to its original format something like this could be done:
sed 's/\\n/\'$'\n''/g'
You can also just echo the single line in the shell which would interpret the \n
as a newline.
Powershell
(GC 'public.asc') -Replace "\n" "`r`n"
If the header and footer were removed and newlines or newline indicators/characters were removed:
Updates
- If you use Azure CLI to pull down these keys with windows it stores the file encoded as
UTF-32 LE
which could cause issues with search and replace needed to replace\n
with actual newline. Best to re-encode it toASCII
.