GPG --gen -key with password in a separate file - cmd

I want to encrypt a file using a passphrase, which I did using gpg --gen-key to create a key (I used the default options) in the command line, and I also go this to work in an "automated" way without user interaction.
But, I'd like to specify the passphrase stored in a separate file. This is what I'm running now:
gpg --batch --gen-key "D:\Staging\FileContainingKeySettings.txt"
And what's in the file called "FileContainingKeySettings.txt" is this:
%echo Generating a default key
Key-Type: default
Subkey-Type: default
Name-Real: PBJ
Name-Comment: test
Name-Email: PBJ#pbj.com
Expire-Date: 0
Passphrase:blah
%commit
%echo done
So that works and generates the key.
Then I call this:
gpg --batch --yes -r PBJ --output D:\Staging\newEncryptedFile.txt --encrypt
D:\Staging\textfiletobeencrypted.csv
And this works too.
So now I have 1 problem and 1 question. The problem is that I need to specify the passphrase to reference a file that looks like this (but much longer):
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG v1.47
[encoding]
-----END PGP PUBLIC KEY BLOCK-----
instead of using the password where I wrote "blah"^, and I haven't found a way to do this online or from any other team members around me. How can I do that?
Question: I also notice now that the file I was sent containing the encryption key reads at the top
" -----BEGIN PGP PUBLIC KEY BLOCK-----"
...which says it uses PGP (but I am using gpg). I know that gpg and pgp are different and read about them, but can I even do what I'm trying to do using gpg to encrypt a file with a key that was apparently generated with pgp?
(in Windows)

UPDATE: Now I may have gotten this working, although I still have to validate by having the other person decrypt the message (it works fine when I decrypt it). Silly I didn't think of this code change earlier when I've actually tried this before...I simply changed my cmd call from this part:
gpg --batch --gen-key "D:\Staging\FileContainingKeySettings.txt"
to this instead, specifying the passphrase file location here instead:
gpg --batch --passphrase "D:\Staging\FileWithActualKey.txt --gen-key
"D:\Staging\FileContainingKeySettings.txt"
and I took the password line out of the file "FileContainingKeySettings" altogether. I haven't tested this by having the other person decrypt it yet on their end...I hope it worked. At least I didn't get error. But now when I run this line again to actually do encryption, it works:
gpg --batch --yes -r PBJ --output D:\Staging\newEncryptedFile.txt --encrypt
D:\Staging\textfiletobeencrypted.csv

Related

GPG large file decryption duration

I want to encrypt large files on linux with a bash script. When I was looking for methods to accomplish that, I thought about GPG and gave it a try. But when I ran some benchmarks I noticed that en-/decryption of large files takes very long.
Test scenario
I generated a 30GB large file filled with random content. Then I encrypted it with an RSA 4096 bit key. As I understand it, GPG is a hybird-encryption programm which encrypts sessions keys with the RSA Public Key. Therefore the en-/decryption should be done wihtin seconds or at least within a minute, as it uses these session keys to encrypt the actual data, isn't it? But here are the test results - I didnt bother decrypting the file with compressen turn on as it would take me another 2 - 3 hours...
System Specs:
GPG Version: 2.2.19
Arch Linux
Docker
Intel i7
My gpg keys were generated with a config file which contained the following values:
Key-Type: RSA
Key-Length: 4096
Subkey-Type: RSA
Subkey-Length: 4096
Name-Real: some-key-name
Name-Comment: some-key-comment
Expire-Date: 0
Passphrase: 123456789
For encryption i used the following commands:
gpg -q --output /outputFile.txt --recipient some-key-name --encrypt /inputFile.txt (with compression)
gpg -q --output /outputFile.txt -z 0 --recipient some-key-name --encrypt /inputFile.txt (without compression)
This command for decrypting the files:
gpg -q --pinentry-mode loopback --batch --passphrase 123456789 --output /decryptedFile.txt --decrypt /encryptedFile.txt
Test results
Encryption with compression turned on:
real 36m23.096s
user 14m54.920s
sys 2m31.870s
Encryption with compression turned off:
real 21m9.781s
user 1m39.590s
sys 2m20.980s
Decryption with compression turned off:
real 140m13.050s
user 5m5.340s
sys 16m33.020s
Questions
Am I missing something or am I using the tool in a wrong way?
Do you know a better way to encrypt large files with which uses an asymmetric encryption or at least uses it to encrypt the session keys?
PS
I googled very much and didn't find a applicable solution. I also read the man page and didn't find a hint what I might miss or did wrong. Also please be aware that I know that passing the password to gpg that way isn't the most secure way ;)

How do you verify an encrypted and signed file with gpg?

I am trying to get a better understanding of what is going on with gpg.
If you have a file and sign it: gpg --sign file.txt
you can verify it with: gpg --verify file.txt.gpg
when you get a successful output: gpg: Signature made...
But when you sign AND encrypt a file: gpg --encrypt --sign -r test#email.com file.txt
and then run --verify on the encrypted file I get: gpg: verify signatures failed: Unexpected error
I know that I can just call --decrypt on the file and it will verify and decrypt it, but what if I want to verify only?
I figured out the answer to this and then some. So I am going to add some additional information for clarity.
First of all, I realize based on the last line to this answer that gpg uses SIGN THEN ENCRYPT. Which means calling --verify or any variation to verify on an encrypted file will just output gpg: verify signatures failed: Unexpected error. This happens because the signature is "hidden" in encryption, so when you try to call --verify on the file, it will not see a signature.
Secondly, the --decrypt flag will both decrypt the file AND if the file is signed, verify it too.
Here is what --decrypt is doing. It looks at your default secret keyring secring.kbx in ~/.gnupg to use a secret key for decrypting the file. Then after it is decrypted, it looks at your default public keyring pubring.kbx in the folder ~/.gnupg and tries to verify the signature on the file, if it has one.
If it has no signature, it will just decrypt the file.
If it has a signature, but you don't have the public key, it will decrypt the file but it will fail to verify the signature.
If it has a signature and you have the public key, it will decrypt and verify.
With that said, there is no reason to verify a signed file BEFORE decrypting it.
Thirdly, as an added bonus, you can also specify a keyring you want to use for decrypting and verification. Say you want to use a temporary keyring to verify signatures or for what ever reason you want a temporary keyring to decrypt the message too.
You can specify the keyrings for --decrypt to use with the following command:
gpg --secret-keyring path/to/temp/secring.kbx --keyring path/to/temp/pubring.kbx --decrypt file.txt.gpg
This command will look for the secret ring and public ring at the specified paths in order to use those rings for decryption and verification instead of the default rings found in ~/.gnupg. Want to use a default ring with a temp ring? Just omit the flag and path to the ring you want defaulted.
All in all, for encrypted and signed files, if you want to decrypt and verify that file, you need to make sure that the private key for decryption is in your secret keyring and the public key for verification is in your public keyring.
One thing to understand about GPG encrypt & sign, which isn't very well explained, is that the signature can only be verified by the recipient.
Suppose Alice encrypts a file to send to Bob. She will encrypt with Bob's public key, and sign with her private key.
gpg --output encrypted.gpg --recipient B0B0000000000000000000000000000000000000 --armor --sign --default-key A11CE00000000000000000000000000000000000 --encrypt file-to-encrypt.txt
There's no way now for Alice, or anyone who does not have Bob's private key, to verify the signature.
Now Bob will decrypt the file. If it is signed, he'll see information about the signature in the output:
$ gpg --decrypt encrypted.gpg > decrypted.txt
gpg: encrypted with 2048-bit RSA key, ID D83A4C12B3840EBA, created 2020-09-24
"Alice <alice#example.com>"
gpg: Signature made 09/28/20 13:16:47 Eastern Daylight Time
gpg: using RSA key A11CE00000000000000000000000000000000000
gpg: Good signature from "Alice <alice#example.com>" [ultimate]
Note the Signature made and Good signature lines in the output.
$ gpg --encrypt --sign -r test#email.com file.txt
After file.txt.gpg generated, try the command below:
$ gpg -d file.txt.gpg
or just execute:
$ gpg file.txt.gpg

Message Authentication Code for gpg

The gpg software supports symmetric encryption out of the box. That means, it works with a password. But apart from protecting the content it is also important to ensure the Authentication of a message. The idea is to create a hashsum of the file itself together with the password used for encryption. According to [1] a popular “Message Authentication Code” is HMAC. After entering:
gpg --hmac --armor --symmetric --passphrase pwd1 file.txt
gpg: Invalid option "--hmac"
an error message occurs that the switch is not known by the software. How can i use the MAC authentication the right way?
You can't. The reason for the error message is that type of signature is not available with GPG. You'd be better off simply signing and encrypting the file with the standard GPG method. Even if you wanted to use symmetric encryption only, then the recipient would still need to use GPG to decrypt the file. The correct command would be:
gpg -o filename.txt.asc -sear $recipient_key filename.txt
This assumes you also always encrypt to your own key, otherwise the command would be:
gpg -o filename.txt.asc -sear $recipient_key -r $your_key filename.txt
If they don't have a key, you could still sign and encrypt to your own key only and then extract the session key so you could provide that for them to decrypt the file with it:
gpg -o filename.txt --show-session-key -d filename.txt.asc
Then the recipient would be able to decrypt with:
gpg -o filename.txt --override-session-key $session_key -d filename.txt.asc
If you really must use symmetric encryption only, however, you can do it in two setps.
First sign the file:
gpg -o filename.txt.asc -sa filename.txt
Then symmetrically encrypt that file:
gpg -o newfilename.asc -a -c filename.txt.asc
The recipient would then need to run the decryption command twice; first on the symmetrically encrypted file and then a second time on the file it decrypts.
The normal --verify option is only used for checking clearsigned files or files with detached signatures.

How to sign a file with a specific public key and check what key was used for signing in GPG?

I have generated 3 pairs of public and private keys using gpg. I would like to sign a file with one of this 3 public keys and then verify which of this 3 keys was used to sign the file.
How can I accomplish this?
I tried to sign the file with gpg --sign --default-key person1#gmail.com data.txt but do not know if its the right direction. Besides, what about veryfing?
gpg -d data.txt.gpg
Will decrypt the file (default -o is data.txt) and tell you which key signed it. If for some reason having a decrypted copy of the file on disk is a problem you might try
gpg -d -o /dev/null data.txt.gpg
It'll still tell you whether the signature was valid and what key signed it.
To specify which key to use when signing:
gpg --sign -u <key-id> somefile.txt

gpg: decryption failed: Bad session key

I'm trying to decrypt a file using gpg and getting this error:
$ gpg --no-tty --batch --verbose --decrypt --passphrase foo file.enc
Version: GnuPG v1.4.11 (GNU/Linux)
gpg: armor header:
gpg: CAST5 encrypted data
gpg: encrypted with 1 passphrase
gpg: decryption failed: Bad session key
I tried to reload the gpg agent, no luck:
$ gpgconf --reload gpg-agent
How to solve that?
For the record, if somebody will encounter this problem, too:
The problem was, that the encryption was done using gpg version 1.4.11 and the decryption was using gpg version 2.0.22.
After upgrading the encryption to gpg2 (2.0.17), everything worked fine.
I found this, which seems to be the magic that I could not find anywhere else:
Try adding --pinentry-mode loopback to your command. Maybe there is a
problem with your installation / pinentry program so that it does not start or
you are accidentally using a dummy / test pinentry which provides the wrong
passphrase.
I encrypted my file with a passphrase file in batch mode. When I tried to decrypt my file I got the dreaded "bad session key" message.
I created a passphrase file with Vim for Windows, and Vim left \r\n at the end of the text line even though I did not hit carriage return. gpg ignored the \n but retained the \r as part of the passphrase!
Vim for Windows can be induced to not leave \r\n, but it is easier to just use Notepad without a carriage return at the end of line. Best to check your passphrase file with a hexdump to be sure. There are other ways to get hurt by \r\n issues when supplying the passphrase using the command line, so be alert to it.

Resources