How to get public key from private in gpg without using local storage (under ~/.gpg)? - pgp

Look to Subj: How to get public key from private in gpg without using local storage (under ~/.gpg)?
This solution does not satisfy requirements:
$ gpg --import priv.key
$ gpg --export $KEYID >pub.key
$ gpg --delete-secret-and-public-key $KEYID

I don't understand why you aren't happy with the solution you have already come up with, but if for some reason you really want to avoid messing with your personal keyrings, I can offer something else:
gtmp=$(mktemp -d)
gpg --homedir $gtmp --import key
gpg --homedir $gtmp --export key > pub.gpg
rm -rf $gtmp
Or as a convenient BASH function:
# Requires keyfile as 1st argument; optional 2nd argument is output file
gpg_priv_to_pub(){
g=$(mktemp -d)
infile=$1
[[ $# > 1 ]] && outfile=$2 || outfile=${1%.*}_pub.gpg
gpg --homedir $g --import "$infile" 2>/dev/null
KEYID=$(gpg --homedir $g -k --with-colons | awk -F: '/^pub/{print $5}')
gpg --homedir $g --export $KEYID > "$outfile"
rm -rf $g
echo "Public key $KEYID extracted from '$infile' and saved to '$outfile'"
}

Related

How to automate installation of missing GPG keys on Linux

I've been working with Linux containers for several years. I am surprised that I wasn't able to find a thread about this question. Scenario:
I've just added a new package index (/etc/sources.list.d/example.list) and want to install a package, let's call it snailmail.
I run the commands:
apt-get update && apt-get install -y snailmail
I get the following error:
W: GPG error: https://example.com/snailmail/debian stable InRelease:
The following signatures couldn't be verified because the public key is not available:
NO_PUBKEY 7EF2A9D5F293ECE4
What is the best way to automate the installation of GPG keys?
apt-key now seems to be deprecated, I have created a script that will detect and get the missing keys, you can get it here.
#!/bin/sh -e
tmp="$(mktemp)"
sudo apt-get update 2>&1 | sed -En 's/.*NO_PUBKEY ([[:xdigit:]]+).*/\1/p' | sort -u > "${tmp}"
cat "${tmp}" | xargs sudo gpg --keyserver "hkps://keyserver.ubuntu.com:443" --recv-keys # to /usr/share/keyrings/*
cat "${tmp}" | xargs -L 1 sh -c 'sudo gpg --yes --output "/etc/apt/trusted.gpg.d/$1.gpg" --export "$1"' sh # to /etc/apt/trusted.gpg.d/*
rm "${tmp}"
Here's a handy script that can be called during the build process to download and install common GPG keys (from the Ubuntu keyserver):
Prerequisites:
wget
for PUBKEY in $(apt-get update 2>&1 | grep NO_PUBKEY | awk '{print $NF}')
do
wget -q "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x${PUBKEY}" -O - | sed -n '/BEGIN/,/END/p' | apt-key add - 2>/dev/null
done

How to sign a rpm package without typing password?

I am trying to sign an RPM package that I created using GPG without typing the password, typing the password I can sign, however without typing the password is opening the message box Please enter the passphrase to unlock the OpenPGP secret key, I need the password not to be requested when signing the package, as this will be a script executed in "silent mode". I probably have the wrong command, but I'm having a hard time finding the solution.
This is the command I am trying to execute, and even then the password is requested:
gpg --batch --passphrase "78910" --clearsign test-1-0.x86_64.rpm
With this second command, the password is not requested:
echo "78910" | gpg --batch --passphrase-fd 0 --clearsign test-1-0.x86_64.rpm
However, the signature is not performed and returns the error described below:
gpg: signing failed: Inappropriate ioctl for device gpg: /test-1-0.x86_64.rpm: clear-sign failed: Inappropriate ioctl for device
With this third command, the reported error is different:
echo "78910" | gpg --batch --passphrase-fd 0 ~/.gnupg/trustdb.gpg --clearsign test-1-0.x86_64.rpm
Error message:
gpg: Note: '--clearsign' is not considered an option gpg: WARNING: no command supplied. Trying to guess what you mean ... usage: gpg [options] [filename]
This is my code to create the gpg key, i try create without password, but i receive error when the password value is empty.
#!/bin/bash
echo "Key-Type: 1" > gen-key-script
echo "Key-Length: 1024" >> gen-key-script
echo "Subkey-Type: 1" >> gen-key-script
echo "Subkey-Length: 1024" >> gen-key-script
echo "Name-Real: gpg test" >> gen-key-script
echo "Name-Email: test#test.com" >> gen-key-script
echo "Expire-Date: 0" >> gen-key-script
echo "Passphrase: 78910" >> gen-key-script
echo "" >> gen-key-script
#---------------------------------------------------------
# GENERATE THE KEY
#---------------------------------------------------------
gpg --batch --gen-key gen-key-script
#---------------------------------------------------------
# .RPMMACROS
#---------------------------------------------------------
echo "%_gpg_name gpg test <test#test.com>" > ~/.rpmmacros
In case your GPG passphrase is empty:
I am aware this is a bit late answer, but it works for me the best since I don't have GPG passphrase (empty passphrase). You can implement some techniques to pass it securely on CLI without typing it, anyway it you have empty passphrase I think this is a good solution.
echo "" | setsid rpmbuild -bb --sign <filename>.spec
SOURCE: https://rpm-list.redhat.narkive.com/7hkHM9bp/signing-rpms-without-a-passphrase#post4
If you don't want to type the password you'll need to store your private key on disk without being protected by a password. That means that everybody who has access to the key file can sign your packages. Decide if you want that.
If you don't want to protect the key use %no-protection, like this:
echo "%no-protection" > gen-key-script
echo "Key-Type: 1" >> gen-key-script
echo "Key-Length: 1024" >> gen-key-script
echo "Subkey-Type: 1" >> gen-key-script
echo "Subkey-Length: 1024" >> gen-key-script
echo "Name-Real: gpg test" >> gen-key-script
echo "Name-Email: test#test.com" >> gen-key-script
echo "Expire-Date: 0" >> gen-key-script
echo "" >> gen-key-script

Preventing GPG logs from being mixed with output in terminal when using "-o -"

I've used GPG to encrypt string directly from terminal to file like this:
echo "Hello World!" | gpg -c --batch --passphrase SomePassword > some_filename
Now I'm trying to decrypt the file and to output the content in the terminal like this:
gpg --batch -o - --passphrase SomePassword some_filename
It works but the output starts with this two lines:
gpg: AES encrypted data
gpg: encrypted with 1 passphrase
NOTE:
The file does not contain this lines (so it's GPG output).
The version of GPG is 1.4.20
AFAIK, GnuPG outputs its messages to stderr, so You can eliminate them by redirecting stderr to /dev/null:
gpg -d --batch -o - --passphrase SomePassword some_filename 2> /dev/null

run gpg encryption command through cronjob

I have a script which executes the gpg encryption command in a sh script throught cronjob.
This is a part of my script
do
gpg --batch --no-tty --yes --recipient $Key --output $Outputdir/${v}.pgp --encrypt ${v}
echo "$?"
if ["$?" -eq 0 ];
then
mv $Inputdir/${v} $Readydir/
echo "file moved"
else
echo "error in encryption"
fi
done
the echo $? gives value as 2.
tried the bellow command also
gpg --batch --home-dir dir --recipient $Key --output $Outputdir/${v}.pgp --encrypt ${v}
where dir=/usr/bin/gpg
My complete script
#set -x
PT=/gonm1_apps/xfb/ref/phoenix_drop
Inputdir=`grep Inputdir ${PT}/param.cfg | cut -d "=" -f2`
Outputdir=`grep Outputdir ${PT}/param.cfg | cut -d "=" -f2`
Key=`grep Key ${PT}/param.cfg | cut -d "=" -f2`
Readydir=`grep Readydir ${PT}/param.cfg | cut -d "=" -f2`
echo $USER
if [ "$(ls -la $Inputdir | grep -E 'S*.DAT')" ]; then
echo "Take action $Inputdir is not Empty"
cd $Inputdir
for v in `ls SID_090_*`
do
gpg --recipient $Key --output $Outputdir/${v}.pgp --encrypt ${v}
echo "$?"
if ["$?" -eq 0 ];
then
mv $Inputdir/${v} $Readydir/
echo "file moved"
else
echo "error in encryption"
fi
done
cd ${PT}
else
echo "$Inputdir is Empty"
fi
GnuPG manages individual keyrings and "GnuPG home directories" per user. A commmon problem when calling GnuPG from web services or cronjobs is executing them as another user.
This means that the other user's GnuPG does look up keys in the wrong key ring (home directory), and if that's fixed it should not have access permissions to the GnuPG home directory at all (not an issue when running a cron or web server as root, but that shouldn't be done for pretty much this reason first hand).
There are different ways to mitigate the issue:
Run the web server or cron job under another user. This might be a viable solution for cron jobs, but very likely not for web services. sudo or su might help at running GnuPG as another user.
Import the required (private/public) keys to the other user's GnuPG home directory, for example by switching to the www-data or root user (or whatever it's called on your machine).
Change GnuPG's behavior to use another user's home directory. You can do so with --home-dir /home/[username]/.gnupg or shorter --home-dir ~username/.gnupg if your shell resolves the short-hand. Better don't do this, as GnuPG is very strict at verifying access privileges and refuse to work if those are too relaxed. GnuPG doesn't like permissions allowing other users but the owner to access a GnuPG home directory at all, for good reasons.
Change GnuPG's behavior to use a completely unrelated folder as home directory, for example somewhere your application is storing data anyway. Usually, the best solution. Make sure to set the owner and access permissions appropriately. An example would be the option --home-dir /var/lib/foo-product/gnupg.
if
the echo $USER prints as root when executed on cronjob and as
username when executed manually
Then you need to login as the user and use a command such as "crontab -e" to add a cronjob for that user to run your script

Write in a gpg script a passphrase located in an other textfile

I'm working on a script GPG and I would like to write a passphrase in the command encrypt. The passphrase is written on a textfile (passphrase.txt) in the same directory. So my goal is to be capable to write in the script.sh in place of mypassphrase the content of the text file passphrase.txt. I've already looked at the commands grep, sed an awk but encountered some difficulties to use them. Any suggestion ?
the command encrypt :
gpg --passphrase mypassphrase --local-user $1 --recipient $2 --armor --sign --output $3.asc --encrypt $3
You can use:
gpg --passphrase $(tr -d $'\n' < passphrase.txt) --local-user "$1" --recipient "$2" --armor --sign --output "$3.asc" --encrypt "$3"
Explanation:
bash knows command substitution $(), which will return the output of a command:
output=$(command)
The command tr -d $'\n' passphrase.txt will output the contents of mypassphrase.txt but will remove additional new lines (if there are any).
If you can make sure that there are no additional new lines in the password file, you can use the following, faster command:
gpg --passphrase $(< mypassphrase.txt) --local-user "$1" --recipient "$2" --armor --sign --output "$3.asc" --encrypt "$3"

Resources