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.