Create a gist now

Instantly share code, notes, and snippets.

Encrypt a (short) file using someone's public key from github
#!/usr/bin/env bash
# HubCrypt
# ========
#
# Decrypt a file encrypted using hubencrypt (ok, it's just openssl + rsautl +
# your SSH keys). It needs the private key that matches your last public key
# listed at github.com/<user>.keys
#
if [[ $# < 3 ]]; then
echo "Usage: $0 <id_rsa> <infile> <outfile>"
exit 1
fi
key=$1
infile=$2
outfile=$3
openssl rsautl -decrypt -inkey $key -in $infile -out $outfile
#!/usr/bin/env bash
# HubCrypt
# ========
#
# Encrypts a small message using a github user's public key as pulled from
# github.com/<user>.key (ok, the last public key listed).
#
# The message size you can encrypt depends on the size of the RSA key used.
#
# Key size (bits) Maximum Message Size (bytes)
# 768 85
# 1024 117
# 2048 246
# 4096 502
# 8192 1018
#
# The key size (as specified by `-b` when using ssh-keygen) doesn't actually
# have to be a power of 2, and will give you maximum message sizes in between
# these ranges. I leave that as an exercise to the reader. If you want the
# "solution" email me. Or leave a message on the gist this originally came from.
# Whatever.
#
# Note: This assumes that the key is an RSA public key, and that the public
# key you want to use is the last one listed at github.com/<user>.keys
if [[ $# < 2 ]]; then
echo "Usage: $0 <github user> <infile> [outfile]"
exit 1
fi
user=$1
infile=$2
outfile=$2.enc
if [[ $# == 3 ]]; then
outfile=$3
fi
pubkey=/tmp/$user.$RANDOM.pub
echo "Getting the key for $user"
# Grab the last key because they added it last
wget https://github.com/$user.keys --quiet -qO- | tail -n 1 > $pubkey #-O $pubkey
#wget github.com/$user.keys --quiet -qO- | head -n 1 > $pubkey #-O $pubkey
# Need a pem file, so we convert it
echo "Converting public key to a PEM PKCS8 public key"
ssh-keygen -f $pubkey -e -m PKCS8 > $pubkey.pem
if [[ $? != 0 ]]; then
print "Since there was an error creating the public key, we'll exit"
exit 1
fi
echo "Encrypting message"
openssl rsautl -encrypt -pubin -inkey $pubkey.pem -ssl -in $infile -out $outfile
if [[ $? != 0 ]]; then
print "OpenSSL failed. No encrypting your message."
exit 1
fi
echo "All done, cleaning up!"
# Clean up
rm $pubkey
rm $pubkey.pem
@rgbkrk
Owner
rgbkrk commented Dec 6, 2013

Note that this little script chooses the last key listed by default.

Example run:

$ ./hubencrypt.sh smashwilson secrets.txt secrets.txt.enc
Getting the key for smashwilson
Converting public key to a PEM PKCS8 public key
Encrypting message
All done, cleaning up!

Later...

$ ./hubdecrypt.sh ~/.ssh/id_rsa secrets.txt.enc secrets.txt
Enter pass phrase for /home/ash/.ssh/id_rsa:
$ cat secrets.txt
Drink more ovaltine.

Also worth noting that messages need to be small enough to actually be able to be encrypted using just public keys. It does of course depend on your key length. For the 2048 bit RSA keys I was using, openssl craps out around 245 bytes. I really wish I knew how these bounds work out mathematically.

@rgbkrk
Owner
rgbkrk commented Dec 7, 2013
Key size (bits)    Maximum Message Size (bytes)
768                                          85
1024                                        117
2048                                        246
4096                                        502
8192                                       1018
@jschauma
jschauma commented Dec 8, 2013

A version of this that can encrypt large input and has some more convenience glue is here: https://github.com/jschauma/jass http://www.netmeister.org/blog/jass.html

Note that on OS X Mavericks this fails to encrypt, since ssh-keygen(1) there can't convert the RSA key to PKCS8. Something in their OSSLShim. You'd have to install another vanilla version of OpenSSH there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment