#!/bin/sh usage='Usage: crypt [-de] [-o output] [input] Encrypt or decrypt input (default: stdin) to ouput (default: stdout), using ssh rsa key. Options: -d action is decrypt (default: encrypt) -e action is encrypt -o output set ouput (default: stdout)' key="$(mktemp)" trap 'rm -f $key' EXIT # Encrypt stdin to stdout. encrypt() { # Generate a random 256 bits one-time key, for symmetric aes encryption. openssl rand 32 >"$key" # Convert (only once) the ssh RSA public to PKCS8, for openssl. [ -f ~/.ssh/id_rsa.pub.pkcs8 ] || ssh-keygen -e -f ~/.ssh/id_rsa.pub -m PKCS8 >~/.ssh/id_rsa.pub.pkcs8 # Output the one-time key asymmetrically encrypted with the rsa pubkey. openssl pkeyutl -encrypt -pubin -inkey ~/.ssh/id_rsa.pub.pkcs8 <"$key" # Now encrypt stdin to stdout, using the clear otk. openssl aes-256-cbc -pbkdf2 -pass "file:$key" } # Decrypt stdin to stdout. decrypt() { # Recover the aes key from the first 256 input bytes. dd ibs=256 count=1 iflag=direct status=none | openssl pkeyutl -decrypt -inkey ~/.ssh/id_rsa -out "$key" # The remaining input is the payload, decrypt it with the aes key. openssl aes-256-cbc -d -pbkdf2 -pass "file:$key" } cmd=encrypt while getopts :deo: opt; do case $opt in d) cmd=decrypt ;; e) cmd=encrypt ;; o) exec 1>"$OPTARG" ;; *) echo "$usage" >&2; exit 1 ;; esac done shift $((OPTIND - 1)) [ "$1" ] && [ "$1" != "-" ] && exec 0<"$1" "$cmd"