I have my privkey.pem private key in the form
-----BEGIN RSA PRIVATE KEY-----
xxx
-----END RSA PRIVATE KEY-----
I need to make a Bamboo task to connect to a server via ssh using this key. Unfortunately I see that Bamboo can store only variables in one line, so if I paste the key all the "\n" get stripped out so this doesn't work:
eval $(ssh-agent -s)
echo "${bamboo.sshKey}" | ssh-add - > /dev/null
scp -vvv -o StrictHostKeyChecking=no .....
Is there a way to have a private key in a "one line" format readable from ssh-add?
Or, is there a clean way to reparse the key to get again the stripped "\n"?
I realize I am a bit late but solutions with sed and tr didn't work well for me. I ended up using base64 and base64 -d, e.g.
echo "${bamboo.sshkey}" | base64 -d > id_rsa
chmod 600 id_rsa
export GIT_SSH_COMMAND='ssh -i id_rsa -o StrictHostKeyChecking=no'
....
rm id_rsa
Using a variable name like sshkey makes Bamboo mask it.
I do not know Bamboo. So possibly, there's a better solution. But one way would be to use some symbol to separate the lines in the variable. And then use something like sed or tr to convert the symbol to a new line, when feeding it to the ssh-add.
See Replace comma with newline in sed on MacOS?
I had a question where I asked about dumping a tar'ed folder to an SSH target. This is useful when backing up servers that have no enough disk space. The solution I got and it works, is this:
tar czv <stuff to backup> | ssh user#server.com 'cat > /home/user/backupfolder/backup.tar.gz'
But the problem now is that I usually pipe tar to openssl to encrypt my packages with
tar zcpf / | openssl des3 -salt | dd of=backup.des3
My question: Now I wanna do the same, but with dumping the resulting archive directly into the SSH target, as given in that answered question but with OpenSSL encryption.
I tried the following:
tar zcpf / | openssl des3 -salt | ssh user#backupserver.com 'cat > /some/dir/backup.tar.gz'
This causes a race between the password asked by OpenSSL and the password asked by ssh, which results in a problem making OpenSSL refuse the input password when repeating it.
Note: Using a public key for logging in without a password isn't considered a useful solution for my case. (EDIT: Also passing the password to OpenSSL is not a solution).
Is there a way to do this without problems? I see the solution as to have OpenSSL ask me about the password, and then ssh ask me about the password, with no racing between them.
Thanks in advance. If you require any additional details, please ask.
You can pass the password with pass argument to encryption.
This should prevent seeking of encryption password later in time and then clash with the password prompt for SSH.
tar zcpf / | openssl des3 -salt -pass pass:1234 | ssh user#backupserver.com 'cat > /some/dir/backup.tar.gz'
EDIT:
This answer does not suit the OP's requirement. The edit made later mentions that passing password as argument is not acceptable.
So I finally managed to create my own bash script that will do the job and fix the problem. Remember that the script has to be run as root if you want to backup the root folder. You can make it fancier by adding root checker at the beginning of the script.
#!/bin/bash
dirToBackup=/
targetDir=/path/to/encrypted/backup/file.des3
sshuser=user
sshserver=myserver.com
read -s -p "Enter Encryption Password: " mypassword1
printf "\n"
read -s -p "Repeat Encryption Password: " mypassword2
printf "\n"
#make sure the passwords match
if [ "$mypassword1" != "$mypassword2" ]
then
echo "Passwords don't match! Exiting."
exit
else
#if they match, make sure they're not empty
if [ -z "$mypassword1" ]
then
echo "Password cannot be empty... Exiting."
else
tar zcp $dirToBackup | openssl des3 -salt -pass pass:$mypassword1 | ssh ${sshuser}#${sshserver} "dd of=${targetDir}"
fi
fi
I would like to encrypt a string without writing it to a file.
The way to encrypt a file using GPG is
gpg --encrypt --sign --armor -r <target#email.com> -r <sender#email.com> <filename.txt>
What I want would like is to be able to simply type in a string or a series of numbers where filename.txt is, and have it encrypt that into a file.
gpg --encrypt --sign --armor -r <target#email.com> -r <sender#email.com> <"this is a string that needs to be encrypted">
Is there a way to do this, or is passing in the filename.txt required?
I'm not aware of any option that allows you to pass input as a parameter, but you can simply use a pipe instead:
echo 'foo bar' | gpg -r target#example.com --encrypt
You can of course add all the additional options and commands you used. By using a pipe, the output is not stored as an intermediate file, but echos stdout and gpgs stdin get connected using a small in-memory buffer.
If you are using bash, you can use the HEREDOC syntax, which is useful for multiline strings. You can just copy and paste the multiline string without having to worry about escaping.
gpg -r target#email.com --encrypt -o out.gpg << 'HEREDOC'
first line
second line
HEREDOC
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
Hi I am fairly new to expect scripting. I am trying to use the gpg for password encryption/decryption. Encryption has no issues. For Decryption, I am trying to automate it using expect script.
The basic command I am trying to use is: gpg -o -d <.gpg file with encrypted password>
When I run this command, stand alone, it asks for passphrase, when I enter it, it creates the output file, as expected. The output file has password in it.
When I run this command using an expect script so that the passphrase can be provided automatically at run time, the expect does not create the output file.
Any help is appreciated. It does not show any errors! The output is:
spawn gpg -o /home/gandhipr/passwdfile -d /home/gandhipr/passfile.gpg
gpg: CAST5 encrypted data
Enter passphrase:
Below is my expect script.
#!/usr/bin/expect
set timeout 1
set passdir [lindex $argv 0]
set passfile [lindex $argv 1]
set passfilegpg [lindex $argv 2]
set passphrase [lindex $argv 3]
spawn gpg -o $passdir$passfile -d $passdir$passfilegpg
expect "Enter passphrase:"
send "$passphrase\n"
exp_internal 1
exit 0;
interact
Use \r instead of \n in the send command: \r is the carriage return characters which mimics the user hitting Enter.