GPG - Change passphrase non interactively - encryption

Most other GPG commands allow you to use --batch mode, but it doesn't appear to be the case when trying to edit a passphrase.
You have to run gpg --edit-key user
Which opens up an interactive GPG prompt.
This isn't going to work in my case as I need the ability to change the passphrase without the command line interaction.
The closest thing I've found is
gpg --batch --passphrase-fd 0 --status-fd 2 --command-fd 0 --edit-key
But this just gives me an invalid command after I enter the existing passphrase.
Any suggestions greatly appreciated.

I just encountered this problem while writing a key-gen script and came up with a solution!
A few things to note:
Lots of folks point towards --batch because --passphrase* requires it. In this case we'll be working with STDIN (as specified by --command-fd 0) and thus want to pass raw input rather than messing with the GnuPG functions.
While --status-fd 2 is useful for debugging, it isn't necessary. That said, including it lead me to the insight that --change-passphrase is requesting two, and only two, entries.
Set --pinentry-mode loopback to avoid having a prompt asking for your passphrase.
The solution is to pipe (or redirect) both the original and new passphrases to STDIN where GnuPG can processes them. While my initial code used (echo ..;echo ..)|gpg .. it is better to use a here-document.
# Using GnuPG to change PGP key passphrase non-interactively
gpg --command-fd 0 --pinentry-mode loopback \
--change-passphrase ${KEYID} <<END
${OLD_PASS}
${NEW_PASS}
END
Just set up the variables and that should work. Enjoy!

Related

GNUPG Decryption command line

Am trying to decrypt an encrypted file, I have all the keys in place (secret and public), I don't know why its not generating output file. Following are the commands am running. I know there are several post already there but I cant refer them until and unless any error flashes on my command prompt.
gpg --list-secret-keys
Its listing secret keys
gpg --list-keys
Its listing all keys
gpg --import "c:\folder_location\name_PublicKey.gpg"
successfully imported keys
gpg --batch --yes --passphrase my_passphrase --local-user "mycomp name
" -o "c:\folder_location\filenameTEST.txt" -d
"c:\folder_location\ENCRYPTEDFILE.txt.gpg"
Am not able to decrypt file on command line, There is no error reported on command prompt. Command remains Active all the time, needed force close.
Anything am missing here to check? any suggestions?
There was no issue with my command, actual problem was CR and LF control characters (new line). When I removed those characters, decryption worked without any errors! GPG never detected these characters and statement got parsed without any error, and later command froze without any error/output.

GnuPG Automating Sign+Encrypt - passphrase-fd 0 issues on Windows

I am currently writing a batch script to automate signing and encrypting files, on GnuPG version 2.0.30.
Can someone explain why the following will not work on my Windows machine:
echo "passphrase"| gpg2 --batch --yes --always-trust --passphrase-fd 0 -es -r "Public key for encryption" "Path of file to encrypt"
To my knowledge, this should be piping the output of echo (my passphrase) as the input of --passphrase-fd 0 (0 operating on STDIN handle of course). I can't seem to get this to work, and wasn't sure if it was my code, or if it's just an issue running this on Windows.
Whenever I execute this command, I get
"no default secret key: Bad passphrase"
"sign+encrypt failed: Bad passphrase"
As a workaround, I was able to use redirection operater < and passed the filepath to my passphrase, still using the STDIN handle (0):
gpg2 --batch --yes --always-trust --passphrase-fd 0 -es -r "Public key for encryption" "Path of file to encrypt" < "Filepath to passphrase"
I realize it's bad practice to store a passphrase in a local file, and may consider removing the signature altogether, but for my own sake, I want to better understand why this won't work using piping (on Windows).
Thanks!

Encrypting file using GnuPG on command line hangs forever

There is one file I want to encrypt with GnuPG by
gpg2 --homedir=~/.gnupg --always-trust=true --recipient="BlahBlah" --encrypt=/path/to/file --output=/path/to/output_file
However this command seems to hang forever and never return. Interestingly, after I interrupt process, there is indeed /path/to/output_file created , however the bytes written there is much bigger than raw payload (for example my /path/to/file is only of 5 bytes but it turns out there are nearly 200 bytes written to /path/to/output_file).
There must be something wrong, but I really couldn't figure out what is it.
I have in advance imported the key for BlahBlah by gpg --import key.asc. It happens both for GnuPG 1 and GnuPG 2.
You're applying --encrypt in a wrong way. --encrypt does not expect any parameters, the file(s) to be worked on are passed as very last arguments. Additionally, following the documentation you should pass --output /path/to/output_file instead of --output=/path/to/output_file. Finally, GnuPG distinguishes between options and commands, and options should precede commands.
What you observe is that GnuPG starts writing header information, but then waits for input from STDIN (until interrupted).
The GnuPG command line you're looking for is
gpg2 --homedir=~/.gnupg --always-trust=true --recipient="BlahBlah" --output /path/to/output_file --encrypt /path/to/file
One last hint: the combination of --always-trust=true and resolving a recipient by user ID is a very bad idea, as any other key with the same user ID in the local keyring might be used. Pass the full key's fingerprint instead, which specifically selects a distinct key (using short key IDs is not secure, either).

GPG: How to sign with multiple signatures with different passphrases?

I have a job that runs periodically and signs/encrypts a file like so:
$ gpg --homedir /path/to/.gnupg -r key1#mydomain.com -r key2#mydomain.com --local-user sig1#mydomain.com --batch --passphrase-file /path/to/gpg-password --sign -ea myfile
The command encrypts the file for two recipients: key1#mydomain.com and key2#mydomain.com. It signs the file with sig1#mydomain.com. It runs in batch mode as there is no human interactivity - this is an automated process. It gets the passphrase for the signature from /path/to/gpg-password.
What I would like to do is now sign the file with two signatures at the same time. Like so:
$ gpg --homedir /path/to/.gnupg -r key1#mydomain.com -r key2#mydomain.com --local-user sig1#mydomain.com --local-user sig2#mydomain.com --batch --passphrase-file /path/to/gpg-password --sign -ea myfile
gpg: skipped "sig2#mydomain.com": bad passphrase
It works fine in interactive mode (eg. without --batch), I just have to supply the two passphrases via the command line. However, in batch mode it fails as it tries to get the signatures from the file. The signature is only valid for one of the signing keys.
From the man page:
--passphrase-file file
Read the passphrase from file file. Only the first line will be read from file file. This can only be used if only one passphrase is supplied.
How do I tell it what the password is for each key?
You have different options.
Completely remove the passwords, since they're stored somewhere anyway.
Use the same password (as you already discovered).
Use the gpg-agent and preset the passphrase. I'm unsure whether this is GnuPG 2-only (usually installed as gpg2, maybe to be installed from a gnupg2 package). Presetting the passphrase is as easy as running gpg-preset-passphrase --preset [fingerprint]. You will have to run this command for each of the keys individually, and make sure to cache the passphrase for a given time (at least the processing time of adding all the passphrases, and then signing the file you want to sign).
For the sake of completeness, but impractical: sign the file individually for each key, then take apart the OpenPGP packets and recombine them adding all the signatures one after the other. Signing with multiple keys just creates multiple signature packets.
For anyone else in the same situation as me, I ended up working around this apparent deficiency of gpg by editing one of the signing keys to have the same password as the other (the password stored in the gpg-password file). This doesn't compromise security in this instance since the password is stored in a text file anyway - the real security is the password of the user that this commands runs from and the fact that the secret keys are kept secret). You can change the password on a key by doing gpg --edit-key <key_id>, then passwd. Don't forget to save after.

How do I remove the passphrase for the SSH key without having to create a new key?

I set a passphrase when creating a new SSH key on my laptop. But, as I realise now, this is quite painful when you are trying to commit (Git and SVN) to a remote location over SSH many times in an hour.
One way I can think of is, delete my SSH keys and create new. Is there a way to remove the passphrase, while still keeping the same keys?
Short answer:
$ ssh-keygen -p
This will then prompt you to enter the keyfile location, the old passphrase, and the new passphrase (which can be left blank to have no passphrase).
If you would like to do it all on one line without prompts do:
$ ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
Important: Beware that when executing commands they will typically be logged in your ~/.bash_history file (or similar) in plain text including all arguments provided (i.e. the passphrases in this case). It is, therefore, is recommended that you use the first option unless you have a specific reason to do otherwise.
Notice though that you can still use -f keyfile without having to specify -P nor -N, and that the keyfile defaults to ~/.ssh/id_rsa, so in many cases, it's not even needed.
You might want to consider using ssh-agent, which can cache the passphrase for a time. The latest versions of gpg-agent also support the protocol that is used by ssh-agent.
$ ssh-keygen -p worked for me
Opened git bash. Pasted : $ ssh-keygen -p
Hit enter for default location.
Enter old passphrase
Enter new passphrase - BLANK
Confirm new passphrase - BLANK
BOOM the pain of entering passphrase for git push was gone.
Thanks!
You might want to add the following to your .bash_profile (or equivalent), which starts ssh-agent on login.
if [ -f ~/.agent.env ] ; then
. ~/.agent.env > /dev/null
if ! kill -0 $SSH_AGENT_PID > /dev/null 2>&1; then
echo "Stale agent file found. Spawning new agent… "
eval `ssh-agent | tee ~/.agent.env`
ssh-add
fi
else
echo "Starting ssh-agent"
eval `ssh-agent | tee ~/.agent.env`
ssh-add
fi
On some Linux distros (Ubuntu, Debian) you can use:
ssh-copy-id -i ~/.ssh/id_dsa.pub username#host
This will copy the generated id to a remote machine and add it to the remote keychain.
You can read more here and here.
To change or remove the passphrase, I often find it simplest to pass in only the p and f flags, then let the system prompt me to supply the passphrases:
ssh-keygen -p -f <name-of-private-key>
For instance:
ssh-keygen -p -f id_rsa
Enter an empty password if you want to remove the passphrase.
A sample run to remove or change a password looks something like this:
ssh-keygen -p -f id_rsa
Enter old passphrase:
Key has comment 'bcuser#pl1909'
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.
When adding a passphrase to a key that has no passphrase, the run looks something like this:
ssh-keygen -p -f id_rsa
Key has comment 'charlie#elf-path'
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.
On the Mac you can store the passphrase for your private ssh key in your Keychain, which makes the use of it transparent. If you're logged in, it is available, when you are logged out your root user cannot use it. Removing the passphrase is a bad idea because anyone with the file can use it.
ssh-keygen -K
Add this to ~/.ssh/config
UseKeychain yes
On windows, you can use PuttyGen to load the private key file, remove the passphrase and then overwrite the existing private key file.
In windows for me it kept saying
"id_ed25135: No such file or directory" upon entering above commands. So I went to the folder, copied the path within folder explorer and added "\id_ed25135" at the end.
This is what I ended up typing and worked:
ssh-keygen -p -f C:\Users\john\.ssh\id_ed25135
This worked. Because for some reason, in Cmder the default path was something like this C:\Users\capit/.ssh/id_ed25135 (some were backslashes: "\" and some were forward slashes: "/")
If you have set a passphrase before and is using mac, use the keychain instead, you'll need to enter your passpharase for the last time and that's it
ssh-add --apple-use-keychain ~/.ssh/id_rsa
Enter passphrase for /Users/{{user_name}}/.ssh/id_rsa:
Identity added: /Users/{{user_name}}/.ssh/id_rsa(/Users/{{user_name}}/.ssh/id_rsa)
If you are using Mac
Go to .ssh folder
update config file by adding "UseKeychain yes"

Resources