8 rsacrypt - Encrypt/decrypt files with RSA
28 sha256sum
-b | cut
-b 1-64
33 say Error occured
in subprocess
, killing main process
34 kill $mainpid 2>/dev
/null
40 if [ -n "$1" -a "$1" != - ]
47 die Give
at most one
file or pipe data on STDIN
for ${mode}ion
52 # Default key files are the user's own RSA keys default used for ssh.
53 # Use -r and -k options to change.
54 keyfile
=$HOME/.ssh
/id_rsa
55 pubfile
=$HOME/.ssh
/id_rsa.pub
56 # Default mode is encryption.
59 # Sign encrypted data and verify signature by default.
71 say
"Usage: $0 [Options] [FILE]
73 --encrypt, -e encrypt (default)
75 --recipient, -r PUBLIC_KEY
77 --no-sign, -S do not sign the secret, and do not search for the signature
78 at the end of data when decrypting
79 --ignore-sign --sign-bytes, -S -b N
80 there is an N bytes long signature at the end of data, but
83 write/read signature to/from a separated file
101 -S|
--no-sign|
--ignore-sign)
117 die Invalid option
: $1
131 if [ -z "$filename" ]
136 if [ $mode = encrypt
-a -t 1 ]
138 die Encrypted data not written to a terminal. Use output redirection.
143 set -o errexit
-o pipefail
148 if file -b "$pubfile" |
grep -q OpenSSH
150 if [ ! -e "$pubfile.pem" ]
152 say Convert
$pubfile to
$pubfile.pem
153 ssh-keygen
-f "$pubfile" -e -m PKCS8
>"$pubfile.pem"
157 say Using public key
: $pubfile
159 if [ $mode = encrypt
-o \
( $mode = decrypt
-a $sign = yes \
) ]
161 die Public key not found
: $pubfile
166 say Using private key
: $keyfile
168 if [ $mode = decrypt
-p \
( $mode = encrypt
-a $sign = yes \
) ]
170 die Private key not found
: $keyfile
177 if [ $mode = encrypt
]
179 say Generating passkey
180 pass
=`openssl rand -base64 32`
181 echo -n "$pass" | openssl rsautl
-encrypt -inkey "$pubfile" -pubin
185 hash=`tee /dev/fd/4 <"$filename" \
186 4> >(set -o errexit -o pipefail;
187 trap subshell_exception ERR;
188 openssl enc -aes-256-cbc -salt -pass pass:$pass >&3) |\
194 if [ -z "$signfile" ]
200 openssl rsautl
-sign -inkey "$keyfile" >"$signfile"
202 elif [ $mode = decrypt
]
204 if [ -z "$signbytes" ]
206 # Find out how many byte the signature is.
209 if [ -z "$signfile" ]
211 # There is no separated signature file,
212 # signature is as long as recipient's key.
213 bits
=`openssl rsa -text -noout -in "$pubfile" -pubin | sed -e '1s/.*(\([0-9]\+\) bit.*/\1/;q'`
215 say Signature bytes
: $signbytes
225 say Extracting passkey
226 pass
=`head -c $bs | openssl rsautl -decrypt -inkey "$keyfile"`
229 # Feed openssl with crypted data except the signature at the end of it,
230 # send openssl's output to main stdout (ie. fd/3 in the inner subshell),
231 # calc checksum and put it on outer subshell's stdout captured by $hashes.
232 # In parallel, feed an other openssl with data stream's end for signature
233 # verification, let stored signature also captured by $hashes.
235 hashes
=(`tee /dev/fd/4 \
236 4> >(set -o errexit -o pipefail;
237 trap subshell_exception ERR;
238 head -c -$signbytes |\
239 openssl enc -d -aes-256-cbc -pass pass:$pass |\
242 1> >(set -o errexit -o pipefail;
243 trap subshell_exception ERR;
246 if [ -z "$signfile" ]
252 openssl rsautl -verify -inkey "$pubfile" -pubin |\
259 if [ "${hashes[0]}" = "${hashes[1]}" ]
263 die Signatures mismatch