Encrypt files with ssh-agent
, bury your secrets.
$ sshovel message.txt message.txt.enc
sshovel: encrypting with SHA256:ypIkIqg6YZAiYrCKzxaFYAtuEpfu5vAlKFN22+lxHic "/tmp/key" and scrypt
sshovel: waiting for scrypt...
$ sshovel message.txt.enc | mocking-spongebob
sshovel: decrypting with SHA256:ypIkIqg6YZAiYrCKzxaFYAtuEpfu5vAlKFN22+lxHic "/tmp/key" and scrypt
sshovel: waiting for scrypt...
hElLo, WoRld!
Edit encrypted files, even if they aren't already encrypted, or don't even exist!
$ sshovel --edit my-secret-file
sshovel: new file, no decryption needed!
...
sshovel: encrypting with SHA256:ypIkIqg6YZAiYrCKzxaFYAtuEpfu5vAlKFN22+lxHic "/tmp/key" and scrypt
$ sshovel --help
usage: sshovel [--cipher CIPHER] [IN] [OUT]
sshovel --edit FILE
Encrypt files with ssh-agent, bury your secrets
positional arguments:
IN optional path, or "-" for stdin, which is the default
OUT as above, with stdout as the default
optional arguments:
-h, --help show this help message and exit
--key MATCH use the ssh key whose comment matches MATCH
--cipher TOOL encrypt with "scrypt" or "openssl" (this can also be
set in the environment with SSHOVEL_CIPHER)
--fingerprint-hash HASH
algorithm used to display fingerprints
--edit FILE decrypt, edit with $EDITOR, and re-encrypt
--test [ARGS [ARGS ...]]
run the test suite
examples:
- Default is to use scrypt(1) to encrypt:
$ sshovel message.txt message.txt.enc
- If the input is encrypted, then the default action is to decrypt:
$ sshovel message.txt.enc
Hello, world!
- Edit an encrypted file in place (or edit then encrypt, if it's plaintext):
$ sshovel --edit secrets
- Use a specific agent key (only needed for encrypt):
$ sshovel --key my_other_key
sshovel is a proof of concept and almost certainly a good example of why rolling your own cryptography, without review, is a bad idea!
- Pure Python 2.7!
- No dependencies!
- ...except for scrypt(1), but you can use openssl(1) instead!
- Single file script!
- Easy to read!
- Self-testing!
- Whimsical name!
sshovel assumes you are a running an ssh-agent loaded with at least one key.
It will get a list of keys from the agent and pick the first one,
or the one whose comment field matches the --key
option,
and then asks the ssh-agent to sign some random data with that key.
The signature is used as a passphrase for the scrypt(1) symmetric encryption tool. You can also use openssl's command line tool if scrypt isn't available.
sshovel inspects the input data to see if it is already encrypted.
If it is, then it will attempt decryption, otherwise encryption is the default.
You can omit arguments to read from stdin
/ write to stdout
.
You can also use -
.
# date | sshovel | sshovel - file && cat file
Mon May 29 03:04:26 LOL 2017
The encrypted file contains the following data:
- sshovel's magic number and version;
- the underlying tool used to encrypt the input file, either "scrypt" or "openssl";
- the public ssh key and the key's comment field;
- the random data whose signature was used as the scrypt/openssl passphrase; and
- the original file, encrypted with scrypt/openssl
Decrypting involves asking the ssh-agent to sign the random data again, with the key listed in the encrypted file. If this is successful then the original scrypt passphrase can be regenerated and the body decrypted.
The ssh-agent functions that sshovel uses are:
-
Get a list of public-keys in the agent.
-
SIGN_REQUEST(public-key, data)
Sign
data
with the private key corresponding topublic-key
.
Another approach I looked at was using the public and private parts of a key pair to perform public key cryptography. This has all the usual advantages: being able to encrypt a file for someone else, and being able to encrypt files for yourself without having to interact with either ssh-agent or the hardware security module containing the private key. However, this approach requires having the private key available as a file -- the ssh-agent approach doesn't expose the private key, and if using an HSM, then you don't have access to the key at all. This is more restrictive than sshovel's approach.
- SSH Agent Protocol -- Damien Miller, IETF: the ssh-agent protocol draft RFC.
- ssh-crypt: encrypt secrets with the SSH Agent: a similar tool to sshovel, written in golang by @leighmcculloch.
- Yubico: Using PIV for SSH through PKCS11: how to set up a Yubikey with an ssh key-pair.
- Stanford IT: Yubikey PIV for SSH: requiring a physical presence test for the Yubikey ssh key.
- Twisted Conch: an SSHv2 implementation written in Python: a good source of documentation on SSH internals.
- Stack Overflow: Creating a rsa public key from its modulus and exponent
- Convert an ssh-keygen public key into OpenSSL PEM format