Skip to content

Instantly share code, notes, and snippets.

@s1037989
Forked from ezimuel/sign.sh
Last active March 15, 2025 23:17
Show Gist options
  • Save s1037989/513e8c29b89fb4f53b79927c0f7ec0d7 to your computer and use it in GitHub Desktop.
Save s1037989/513e8c29b89fb4f53b79927c0f7ec0d7 to your computer and use it in GitHub Desktop.
Sign and verify a file using OpenSSL command line tool. It exports the digital signature in Base64 format, and there are functions for storing the signature in the linux extended attributes.
function gen_keys {
[ -z "$1" ] && { echo "Usage: $FUNCNAME passphrase"; return 1; }
local passphrase="$1" privatekey=$(mktemp) publickey=$(mktemp)
openssl genrsa -aes128 -passout pass:"$passphrase" -out $privatekey 2048 >/dev/null
openssl rsa -in $privatekey -passin pass:"$passphrase" -pubout -out $publickey >/dev/null
printf "Private Key: %s\nPublic Key: %s\n" $privatekey $publickey
}
function sign_file {
[ -z "$2" ] && { echo "Usage: $FUNCNAME file privatekey publickey"; return 1; }
local file="$1" privatekey="$2" publickey="$3" dgst=$(mktemp) sig=$(mktemp) signedfile=$(mktemp)
trap "rm -f $dgst $sig" RETURN
openssl dgst -sha256 -sign $privatekey -out $dgst $file >/dev/null || return 1
openssl base64 -in $dgst -out $sig >/dev/null || return 1
cat $sig $publickey $file > $signedfile && echo $signedfile
}
function extract_file {
[ -z "$1" ] && { echo "Usage: $FUNCNAME signedfile"; return 1; }
local signedfile="$1" sig=$(mktemp) publickey=$(mktemp) dgst=$(mktemp) file=$(mktemp)
trap "rm -f $dgst $sig $publickey" RETURN
dd skip=0 count=350 if=$signedfile bs=1 of=$sig &>/dev/null || return 1
dd skip=350 count=451 if=$signedfile bs=1 of=$publickey &>/dev/null || return 1
dd skip=801 if=$signedfile bs=1 of=$file &>/dev/null || return 1
openssl base64 -d -in $sig -out $dgst >/dev/null || return 1
openssl dgst -sha256 -verify $publickey -signature $dgst $file >/dev/null && echo $file
}
function xunsign {
[ -z "$1" ] && { echo "Usage: $FUNCNAME file"; return 1; }
setfattr -x user.sec.sha256 "$1"
setfattr -x user.sig.signature "$1"
}
function xchecksec {
[ -z "$1" ] && { echo "Usage: $FUNCNAME file"; return 1; }
local file="$1" sec=$(mktemp)
if getfattr --only-values -n user.sec.sha256 "$file" &>/dev/null; then
sha256sum -c <(printf "%s %s" $(getfattr --only-values -n user.sec.sha256 "$file") "$file") &>/dev/null || return
fi
for required_attr in classified_by classification; do
getfattr --only-values -n user.sec.$required_attr "$file" &>/dev/null || return
done
}
function xsign {
[ -z "$2" ] && { echo "Usage: $FUNCNAME file privatekey"; return 1; }
local file="$1" privatekey="$2"
setfattr -n "user.sec.sha256" -v "$(sha256sum "$file" | cut -b1-64)" "$file"
xchecksec "$file" || return
setfattr -n user.sig.signature -v $(openssl dgst -sha256 -sign "$privatekey" <(getfattr -m "^user\\.sec\\." "$file" | sha256sum | cut -b1-64) | base64 | paste -s -d '') "$file"
}
function xsetsec {
[ -z "$3" ] && { echo "Usage: $FUNCNAME sec value file"; return 1; }
case "$1" in
classification|classified_by) setfattr -n "user.sec.$1" -v "$2" "$3";;
*) return 1;;
esac
}
function xchecksig {
[ -z "$1" ] && { echo "Usage: $FUNCNAME signedfile trusted_pubkey_path"; return 1; }
local signedfile="$1" sigpath="$2"
getfattr --only-values -n user.sec.sha256 "$signedfile" &>/dev/null || return
getfattr --only-values -n user.sig.signature "$signedfile" &>/dev/null || return
xchecksec "$signedfile" || return
local -
shopt -s nullglob
for trusted_pubkey in $sigpath/*; do
openssl dgst -sha256 -verify "$trusted_pubkey" -signature <(getfattr --only-values -n user.sig.signature "$signedfile" | fold -w 76 | base64 -d) <(getfattr -m "^user\\.sec\\." "$signedfile" | sha256sum | cut -b1-64) && return
done
return 1
}
#!/bin/bash
# Sign a file with a private key using OpenSSL
# Encode the signature in Base64 format
#
# Usage: sign <file> <private_key>
#
# NOTE: to generate a public/private key use the following commands:
#
# openssl genrsa -aes128 -passout pass:<passphrase> -out private.pem 2048
# openssl rsa -in private.pem -passin pass:<passphrase> -pubout -out public.pem
#
# where <passphrase> is the passphrase to be used.
filename=$1
privatekey=$2
if [[ $# -lt 2 ]] ; then
echo "Usage: sign <file> <private_key>"
exit 1
fi
openssl dgst -sha256 -sign $privatekey -out /tmp/$filename.sha256 $filename
openssl base64 -in /tmp/$filename.sha256 -out signature.sha256
rm /tmp/$filename.sha256
#!/bin/bash
# Verify a file with a public key using OpenSSL
# Decode the signature from Base64 format
#
# Usage: verify <file> <signature> <public_key>
#
# NOTE: to generate a public/private key use the following commands:
#
# openssl genrsa -aes128 -passout pass:<passphrase> -out private.pem 2048
# openssl rsa -in private.pem -passin pass:<passphrase> -pubout -out public.pem
#
# where <passphrase> is the passphrase to be used.
filename=$1
signature=$2
publickey=$3
if [[ $# -lt 3 ]] ; then
echo "Usage: verify <file> <signature> <public_key>"
exit 1
fi
openssl base64 -d -in $signature -out /tmp/$filename.sha256
openssl dgst -sha256 -verify $publickey -signature /tmp/$filename.sha256 $filename
rm /tmp/$filename.sha256
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment