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

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"

Related

Recursive decryption using gpgdir

I have a lot of files that are encrypted with gpg in a lot of directories. So I want to use gpgdir command to decrypt recursively all files in all directories.
The problem is in the use of gpgdir. I installed it correctly and I set the correct defualt key id in my conf file using gpg --list-keys to find the id. But when I use the command
gpgdir -decrypt <directory>
the console gives me back
[+] Executing: gpgdir -decrypt <directory>
Using GnuPG key: 3662FD5E
Password:
I don't know what password I must insert to decrypt the files. I tried with the admin password but doesn't work.
Someone can help me?
Thanks!!

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.

ecryptfs - relation of user entered passphrase to the FEKEK when mounting manually

I've been trying to set up encrypted folder following the instructions in https://wiki.archlinux.org/index.php/ECryptfs#Without_ecryptfs-utils. In that case a mount passphrase is manually created and wrapped using a chosen password ("Arch" in that example). This is working as expected.
There is yet another possibility how to manually set up things. Namely using simple mount e.g.:
mount -t ecryptfs ~/.Private/ ~/Private -o key=passphrase,ecryptfs_cipher=aes,ecryptfs_key_bytes=32,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=y
In this case I'm prompted for a [password] and after that folder is mounted.
My question is: where is the mount passphrase hidden in the second example? And how is my entered [password] related to it and to the FEKEK in this case.
Could anybody please explain?
Thank you in advance.
I think the entered passphrase becomes the "file encryption key, encryption key, or FEKEK" itself, and is temporarily stored in the kernel keyring (root's keyring if you need to mount with sudo) while the folder is mounted. You can see the keyring before & after mounting & unmounting with sudo keyctl show.
It does not store the passphrase/FEKEK anywhere on disk, unlike the method "Without ecryptfs-utils" in the ArchWiki you liked to, and the one in the ecryptfs-utils below.
FYI, using the ecryptfs-utils tools it will create a random (16 byte) passphrase to use, if you haven't specified your own passphrase, and it apparently is the file encryption key (FEKEK) / FNEK.
Looking in a couple of the ecryptfs-utils tools, (several are shell scripts) inside ecryptfs-migrate-home it collects some data and calls ecryptfs-setup-private, which has this function to generate a more secure 16 byte random passphrase/FEKEK/FNEK (that then gets "wrapped"/encrypted with your login passphrase and stored on disk):
random_passphrase () {
bytes=$1
# Pull $1 of random data from /dev/urandom,
# and convert to a string of hex digits
od -x -N $bytes --width=$bytes /dev/urandom | head -n 1 | sed "s/^0000000//" | sed "s/\s*//g"
}

How to make auto trust gpg public key?

I am trying to add my GPG public key as a part of our appliance installation process. The purpose of it to encrypt any important files like logs before admin pulling them into his local using admin portal and then decrypt them using private key.
The plan is to export public key into a file and make appliance installation process to import it using gpg --import command. But I realized, the key is needed to be trusted/signed before do any encryption.
How to make this key is trusted without any human intervention at the time of installation?
Btw, our appliance os is ubuntu vm and we use kickstart to automate.
Advance thanks for all help.
Your question is really "How do I encrypt to a key without gpg balking at the fact that the key is untrusted?"
One answer is you could sign the key.
gpg --edit-key YOUR_RECIPIENT
sign
yes
save
The other is you could tell gpg to go ahead and trust.
gpg --encrypt --recipient YOUR_RECIPIENT --trust-model always YOUR_FILE
Coincidentally I have a similar situation to the OP - I'm trying to use public/private keys to sign and encrypt firmware for different embedded devices. Since no answer yet shows how to add trust to a key you already have imported, here is my answer.
After creating and testing the keys on a test machine, I exported them as ascii:
$ gpg --export -a <hex_key_id> > public_key.asc
$ gpg --export-secret-keys -a <hex_key_id> > private_key.asc
Then secure-copied and imported them to the build server:
$ gpg --import public_key.asc
$ gpg --import private_key.asc
Important: add trust
Now edit the key to add ultimate trust:
$ gpg --edit-key <user#here.com>
At the gpg> prompt, type trust, then type 5 for ultimate trust, then y to confirm, then quit.
Now test it with a test file:
$ gpg --sign --encrypt --yes --batch --status-fd 1 --recipient "recipient" --output testfile.gpg testfile.txt
which reports
...
[GNUPG:] END_ENCRYPTION
without adding trust, I get various errors (not limited to the following):
gpg: There is no assurance this key belongs to the named user
gpg: testfile.bin: sign+encrypt failed: Unusable public key
There's an easier way to tell GPG to trust all of its keys by using the --trust-model option:
gpg -a --encrypt -r <recipient key name> --trust-model always
From the man page:
--trust-model pgp|classic|direct|always|auto
Set what trust model GnuPG should follow. The models are:
always Skip key validation and assume that used
keys are always fully trusted. You generally
won't use this unless you are using some
external validation scheme. This option also
suppresses the "[uncertain]" tag printed
with signature checks when there is no evidence
that the user ID is bound to the key. Note that
this trust model still does not allow the use
of expired, revoked, or disabled keys.
Add trusted-key 0x0123456789ABCDEF to your ~/.gnupg/gpg.conf replacing the keyid. This is equivalent to ultimately trusting this key which means that certifications done by it will be accepted as valid. Just marking this key as valid without trusting it is harder and either requires a signature or switching the trust-model to direct. If you are sure to only import valid keys you can simply mark all keys as valid by adding trust-model always. In the latter case ensure that you disable automatic key retrieval (not enabled by default).
This worked for me:
Trying to encrypt a file responds with this:
gpg -e --yes -r <uid> <filename>
It is NOT certain that the key belongs to the person named
in the user ID. If you *really* know what you are doing,
you may answer the next question with yes.
Use this key anyway? (y/N)
That causes my shell script to fail.
So I:
$gpg --edit-key <uid>
gpg> trust
Please decide how far you trust this user to correctly verify other
users' keys (by looking at passports, checking fingerprints from
different sources, etc.)
1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu
Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y
Please note that the shown key validity is not necessarily correct
unless you restart the program.
gpg> quit
Now the encrypt works properly.
Based on #tersmitten's article and a bit of trial and error, I ended up with the following command line to trust all keys in a given keyring without user interaction. I use it for keys used with both StackEschange Blackbox and hiera-eyaml-gpg:
# The "-E" makes this work with both GNU sed and OS X sed
gpg --list-keys --fingerprint --with-colons |
sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |
gpg --import-ownertrust
Personally, I prefer a solution which stores the results in the trustdb file itself rather than depends on user environment outside the shared Git repo.
Here's a trick I've figured out for automation of GnuPG key management, hint heredoc + --command-fd 0 is like magic. Below is an abridged version of one of the scripts that's been written to aid in automation with GnuPG.
#!/usr/bin/env bash
## First argument should be a file path or key id
Var_gnupg_import_key="${1}"
## Second argument should be an integer
Var_gnupg_import_key_trust="${2:-1}"
## Point to preferred default key server
Var_gnupg_key_server="${3:-hkp://keys.gnupg.net}"
Func_import_gnupg_key_edit_trust(){
_gnupg_import_key="${1:-${Var_gnupg_import_key}}"
gpg --no-tty --command-fd 0 --edit-key ${_gnupg_import_key} <<EOF
trust
${Var_gnupg_import_key_trust}
quit
EOF
}
Func_import_gnupg_key(){
_gnupg_import_key="${1:-${Var_gnupg_import_key}}"
if [ -f "${_gnupg_import_key}" ]; then
echo "# ${0##*/} reports: importing key file [${_gnupg_import_key}]"
gpg --no-tty --command-fd 0 --import ${_gnupg_import_key} <<EOF
trust
${Var_gnupg_import_key_trust}
quit
EOF
else
_grep_string='not found on keyserver'
gpg --dry-run --batch --search-keys ${_gnupg_import_key} --keyserver ${Var_gnupg_key_server} | grep -qE "${_grep_string}"
_exit_status=$?
if [ "${_exit_status}" != "0" ]; then
_key_fingerprint="$(gpg --no-tty --batch --dry-run --search-keys ${_gnupg_import_key} | awk '/key /{print $5}' | tail -n1)"
_key_fingerprint="${_key_fingerprint//,/}"
if [ "${#_key_fingerprint}" != "0" ]; then
echo "# ${0##*/} reports: importing key [${_key_fingerprint}] from keyserver [${Var_gnupg_key_server}]"
gpg --keyserver ${Var_gnupg_key_server} --recv-keys ${_key_fingerprint}
Func_import_gnupg_key_edit_trust "${_gnupg_import_key}"
else
echo "# ${0##*/} reports: error no public key [${_gnupg_import_key}] as file or on key server [${Var_gnupg_key_server}]"
fi
else
echo "# ${0##*/} reports: error no public key [${_gnupg_import_key}] as file or on key server [${Var_gnupg_key_server}]"
fi
fi
}
if [ "${#Var_gnupg_import_key}" != "0" ]; then
Func_import_gnupg_key "${Var_gnupg_import_key}"
else
echo "# ${0##*/} needs a key to import."
exit 1
fi
Run with script_name.sh 'path/to/key' '1' or script_name.sh 'key-id' '1' to import a key and assign a trust value of 1 or edit all values with script_name.sh 'path/to/key' '1' 'hkp://preferred.key.server'
Encryption should now be without complaint but even if it does the following --always-trust option should allow encryption even with complaint.
gpg --no-tty --batch --always-trust -e some_file -r some_recipient -o some_file.gpg
If you wish to see this in action, then check the Travis-CI build logs and how the helper script GnuPG_Gen_Key.sh is used for both generating and importing keys in the same operation... version two of this helper script will be much cleaner and modifiable but it's a good starting point.
This oneliner updates the trustdb with the ownertrust values from STDIN -- by extracting the fingerprint to the format required by --import-ownertrust flag.
This flag, as detailed on gpg man page, should be used In case of a severely damaged trustdb and/or if you have a recent backup of the ownertrust values, you may re-create the trustdb.
gpg --list-keys --fingerprint \
| grep ^pub -A 1 \
| tail -1 \
| tr -d ' ' \
| awk 'BEGIN { FS = "\n" } ; { print $1":6:" }' \
| gpg --import-ownertrust
One way to trust imported gpg keys:
gpg --import <user-id.keyfile>
fpr=`gpg --with-colons --fingerprint <user-id> |awk -F: '$1 == "fpr" {print$10; exit}'`
gpg --export-ownertrust && echo $fpr:6: |gpg --import-ownertrust
here, I assume that you import a key with the <user-id> from <user-id.keyfile>. The second line only extracts fingerprint, you can drop it if you know the fingerprint beforehand.
I think, I figured way to do this.
I used 'gpg --import-ownertrust' to export my trust db into a text file then removed all of my keys from it except public key I needed to push. And then imported my public key and edited owner-trust file on to server. This seems like working.
Now I am having trouble implementing these steps in Kickstart file:-(
With powershell, here is how to trust john.doe#foo.bar (adapted from #tersmitten blog post):
(gpg --fingerprint john.doe#foo.bar | out-string) -match 'fingerprint = (.+)'
$fingerprint = $Matches[1] -replace '\s'
"${fingerprint}:6:" | gpg --import-ownertrust
Note: using cinst gpg4win-vanilla
There is a way to autotrust key using --edit-key, but without getting into interactive shell (so can be automated in script). Below is a sample for windows:
(echo trust &echo 5 &echo y &echo quit) | gpg --command-fd 0 --edit-key your#email.com
Unix based:
echo -e "5\ny\n" | gpg --homedir . --command-fd 0 --expert --edit-key user#exaple.com trust;
For more info read this post. It details if you are creating more than one key.
I used following script for import key:
#!/bin/bash
function usage() {
cat >&2 <<EOF
Usage: $0 path_of_private_key
Example: gpg_import.sh ~/.ssh/my_gpg_private.key
Import gpg key with trust.
EOF
exit 1
}
[[ $# -lt 1 ]] && usage
KEY_PATH=$1
KEY_ID=$(gpg --list-packets ${KEY_PATH}/${GPG_PRIVATE_KEY} | awk '/keyid:/{ print $2 }' | head -1)
gpg --import ${KEY_PATH}/${GPG_PRIVATE_KEY}
(echo trust &echo 5 &echo y &echo quit) | gpg --command-fd 0 --edit-key $KEY_ID
I am using windows with gpgwin4.0.2 installed.
Open the Kleopatra (the GUI) -> Certificates -> Right Click -> Certify. Once the has been certify, this message will not show any.
Try this :
(echo trust &echo 5 &echo y &echo quit &echo save) | gpg --homedir 'gpgDirectory/' --batch --command-fd 0 --edit-key 'youKey'
--homedir : not required

Can I include a password in my rsync call?

I use rsync to update my static website. I currently cd to the local website directory, and run the rsync command, and then enter the password in the next line. I've saved my rsync call into a text snippet (such that _rs just expands to my call). Is there way to use something like a -p flag at the end and include the password too?
My call looks like this:
rsync -avzh -e ssh * foo#foo.org:"/home/foo/public_html/"
Answering this with a direct answer to the question, may be useful in less secure scenarios.
#!/usr/bin/expect -f
set PASSPH "123456"
send_user "\n"
stty -echo
spawn rsync -apv -e ssh "/Volumes/Macintosh HD/Users/charliechaplin/test/" "charly#chaplin.com:/project/htdocs/site/"
expect "password:"
send "$PASSPH\n"
expect "#"
One of option is use public/private key pair, see How to auto rsync with ssh passwordless
Or you can try use Expect

Resources