End to end encrypt using ssh key pairs
TLDR
To send a message to someone using his github’s public key
TO=<GITHUB USER NAME> TEXT='<SUPER SECRET TEXT>';
curl -s https://github.com/$TO.keys | ssh-keygen -f /dev/stdin -e -m PKCS8 > $TO.pem.pub;
echo $TEXT | openssl rsautl -inkey $TO.pem.pub -encrypt -pubin -ssl | base64 ;
rm -f $TO.pem.pub
Receiver will use his SSH private key to decrypt
echo "<encrypted text>" | base64 -D | openssl rsautl -decrypt -inkey ~/.ssh/id_rsa
Explanation
Encryption steps
curl -s https://github.com/$TO.keys
First, we will download the public keys of a github user. For example, my public key will be at https://github.com/zinh.keys
ssh-keygen -f /dev/stdin -e -m PKCS8 > $TO.pem.pub
then convert this key to PKCS8 format(.pem) and save it to a temporary file.
echo $TEXT | openssl rsautl -inkey $TO.pem.pub -encrypt -pubin -ssl
after that, use rsautl
of openssl to encrypt a text from stdin, using RSA algorithm with ssl padding.
As the output is in binary format, we will need to encode in base64 for easier sending by pipe the encrypted text to base64 program.
Finally, remove the download key.
Dencryption steps
Decryption is quite straight forward, a user will use his ssh key to decrypt the text(after using base64 to decode).
Refer to openssl rsautl man page for a more detail of the parameters.
Limitation
- Should use to encrypt short message only as RSA is quite slow. In case we need to encrypt long text or file, we should create a symmetric key and use it to encrypt the text then use RSA to encrypt that key.
- As
https://github.com/$USER.keys
will return all public keys of a user, the script will use the last key in this list.