Using Age to Publicly Post Sensitive Data

Written by Paco Pascal, on 11 June 2022.
Tags: #unix #linux #gpg #age #cryptography

1. The Problem

Recently, I had an issue where I was working on a set of remote servers and needed to copy files between different servers. Some of the servers were sandboxes that could've been infected by malicious software; therefore, I didn't want to leak any information in the sandboxes about any production servers or credentials.

My first instinct was to post to pastebin. But I wanted to encrypt the data before posting. Using GnuPG in the sandboxes was problematic. This is where Age provided a convenient solution.

2. The Solution

On a production machine, we can easily create a temporary Age key by doing,

age-keygen -o key.txt

which gives the following output,

Public key: age15v5xqysc8g7spuzdyk0v5q90m609ruaecwnlv2x67zv5xqnju4esp2tz3j

Instead of using, pastebin for posting, we'll use https://0x0.st/ which doesn't require an API key. On the insecure server, do the following,

age --encrypt -r age15v5xqysc8g7spuzdyk0v5q90m609ruaecwnlv2x67zv5xqnju4esp2tz3j -a /path/to/private/file | curl -F 'file=@-' https://0x0.st/

which will output a URL, such as

https://0x0.st/oM5X.txt

Now we can download this file and decrypt it in a safe location.

curl -s https://0x0.st/oM5X.txt | age --decrypt -i key.txt -o secret_file.txt

3. Solution Simplification

We can make this process smoother by writing two scripts. An upload script such as,

#!/bin/sh

RECIPIENTS=${RECIPIENTS:-"$@"}

if [ -z "$RECIPIENTS" ]; then
    echo "Usage: $0 [recipient public key]..."
    exit 1
fi

for r in $RECIPIENTS; do
    AGEFLAGS="${AGEFLAGS} -r ${r}"
done

age $AGEFLAGS -a | curl -F 'file=@-' https://0x0.st/

and a download script such as,

#!/bin/sh

URL=$1
AGEKEY=${2:-key.txt}

if [ -z $URL ]; then
    echo "Usage: $0 url [age key file]"
    exit 1
fi

curl -s $URL | age --decrypt -i ${AGEKEY}

Now if we have two age keys, key-1.txt (age1dwj4jcfp9wfpslrj4gnws5y5llzetdzu0cpndtr96fr3htlgdvusk6w8tg) and key-2.txt (age1xqz970tzhklqp0qyz9x3c3yur3jd65urasmwer0thzc4k6y6qftq7sc2zw), we can upload an encrypted file for both keys by doing,

echo secret text | ./age-post.sh \
  age1dwj4jcfp9wfpslrj4gnws5y5llzetdzu0cpndtr96fr3htlgdvusk6w8tg \
  age1xqz970tzhklqp0qyz9x3c3yur3jd65urasmwer0thzc4k6y6qftq7sc2zw

and download the same content for each key,

1: $ ./age-pull.sh https://0x0.st/oM5_.txt key-1.txt
2: secret text
3: $ ./age-pull.sh https://0x0.st/oM5_.txt key-2.txt
4: secret text