Skip to content

Instantly share code, notes, and snippets.

@tlwr
Last active November 26, 2019 14:18
Show Gist options
  • Save tlwr/7e9a5ae47e8ecd0b909eefb2a5b8fdaf to your computer and use it in GitHub Desktop.
Save tlwr/7e9a5ae47e8ecd0b909eefb2a5b8fdaf to your computer and use it in GitHub Desktop.
CloudFront form field encryption
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA3YsdHLM7+5Go8roGFXtIhKTU26SumkkQCMGg6Y5rD/+n2ZiS
LTQkmXBSFCQth93b/uSqQ1W6QcSWL8o1Ys7X7arQqTgqnfxut4ioNnAEY1dBL8nv
tZcboAfvFQtPMwqL9esk6yH3T66cSIy0TdxMEzzU10PhQhVwUebQ3OFsqdAZtL3F
g5WIP4T+c3Wu+0OQ11eyOWcoqFKTm50Adia10CeEEi9IwiwnpudIWd5ivDLVqe4t
unAmJ9goyK31lUBOrIrMXVE3y4Cps0Mc7RqbBfu6t5NO+DnNWjStOWCgA++VzU8T
nM2VBsP7DA7bmFP1RuML1MFckd9XRPihVucmIQIDAQABAoIBAD2z+ja9IM6vQfvg
ncMr5AW1ludZ1Zt5D/MwYq3KEb2R+eDb4pKefDcUFngvn1LBEv3KGDXK0aZxp1bG
HdpYO8GhGp6W2x/HZ9rMP/Vxe3djnO8/cfkEjhgjPY6B6NwRauviQxUOD8BspHB8
Z9drrPCKt8kAyeNK706QV8m9KzOcEm2dqcqO+WU+sU2zfiJurDkJv92Mb2Q6khBk
WGQ4Si8T/D15VJe5EB6wIYy5x4SlYHq66uhAE4jym6ytzcqtYeXuSYl/hi6uG0kK
9LEwXn4HR9zX6Q6WzWab6rCTts/sPCrzLdnAJTEjr889Pzz53JVYzzzfrwzU1iJR
cPgFlLUCgYEA8u2Fbgh//K/TjVhs5JpvAl1boNxdD2v3eglBQ9e2VsGEcuXO3V9s
bl7pQyz6N28f+u5JiYBjslE+/2V6VOFL2AGeHU6XKzdxQInq0+VmYpLXgCQYMIdW
4iG/ZJTLQg4o33am78sY0YpsqhEtPPeTG/isoOwveKL4eU9JkT+gemcCgYEA6XcC
Yajve1EyMtCMyHGe/EwJ8KOC5cS1VU4bRDg26zuZW3UzcKiOf3WR/uFOMgbzHSeB
KcHeLDY4J8jc49WVrIUGsZz0UFhAzsHWGBSbMLA1v2fvqzfDoQWkCgrAJvHZOV9R
xrUjFfaZeTDkIzCipR1/d1M7V7P/ft4OuVbYFjcCgYEAhDrnyzoTOJ8YXzLHqzOo
wze//XKVsSRKxAGvpdcQKG8Twlr23Cbp5bYB8I/V70CsvrDgFFlvawuwZ+J70SIF
X6GZyEgUHvEB02h/CzIuJe/aH6UGCbxRfaty+7PGY8FDXEfAnHwHmV9owLWy0yHL
0IjupnWJbXgAGkAfQlHI73cCgYAn7TpzCTkrlc9H8XKiNQxDiZ2Jke0o7mM0m47+
M77wq9imU3zgn3L/SVQWiuGcnKOnMMJeKdGdLgichTWBoV1fi8CBT55Yvz8WHQBI
Tf3cbcZDXbsXRQon15ceQIhsIKBNt4d8vC2r6+iDWWEqw36NTmYmOg3ECfx/7eoG
uFtsMQKBgQC3G5JkGrhzX9kFM+zoR1hBZdoKg8l9hBxwqaLk0vMWfI+SCPwQajon
+oMVv10MsFnnlxxcqJl2NXkvG3tZ4krP15QEsPRAHnHIfiUsxJEiGhuUmtBwV1gO
AwB3bQBh0WEYkXGU+eYiAkKyIqIDm2BC8X/M0GmzEuFEDioQpYcNYg==
-----END RSA PRIVATE KEY-----
// This demonstrates how to use an express middleware for decrypting fields
// It uses RSAES-OAEP/SHA-256/MGF1-SHA-1 which is a common encryption format for Java
// Bear in mind most of the code below is boilerplate for express
// The only relevant code is the middleware which decrypts the field
// This does not include error handling or proper logging
// How to use
//
// 1. Run the app
// FIELD_NAMES=cvv PRIVATE_KEY="$(cat /path/to/private.pem)" node index.js
// 2. Send a request to the app
//
// curl localhost:8080 \
// -H 'Content-Type: application/x-www-form-urlencoded' \
// -X POST \
// --data-urlencode 'cvv=dVtpG7qoDPam/3Qm4tTT8eYSVggfWrKi+YIBm9zxgbU7wLUJg5S9cn6yTJY3hff8/fdzk4RVuyjaPlQE1Hndlj7Nd0LuMwgyqLTB0u4uydQPkYOrthwv0aJgou9Y6Vooqbkrfo6QgBYwrPWdK8zrLLqsYdUpPpl9sSBn1sl8WnQawCrYvhwFgM8LSY0YGjHLt+Koc6QoN6aBYXJoNzThIFIlV5lycfrSgqA7NI3HFMJmY/BwOt9H8Xn+irP/tLsKkFdieYer0S3fkJ+Fl8GJ6dPWt+wUqEDlIqVW1qQCfF87S38L7g8F1h66mQxN4oMswuZ5kDfv4TjNjdglBrFEhA=='
const express = require('express')
const bodyParser = require('body-parser')
const forge = require('node-forge');
const rsa = forge.pki.rsa;
const port = parseInt(process.env['PORT'] || '8080', 10)
const fieldNames = process.env['FIELD_NAMES']
const privateKeyPEM = process.env['PRIVATE_KEY']
if (typeof fieldNames === 'undefined' || fieldNames === '') {
throw new Error('Environment variable FIELD_NAMES must be specified')
}
if (typeof privateKeyPEM === 'undefined' || privateKeyPEM === '') {
throw new Error('PRIVATE_KEY must be specified')
}
const fieldsToDecrypt = new Set(fieldNames.split(","))
const privateKey = forge.pki.privateKeyFromPem(privateKeyPEM);
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(function(req, res, next) {
console.info(`Received request for ${req.url}`)
next()
});
app.use(function(req, res, next) {
Object.keys(req.body).forEach(fieldName => {
if (fieldsToDecrypt.has(fieldName)) {
req.body[fieldName] = forge.util.encodeUtf8(
privateKey.decrypt(
forge.util.decode64(req.body[fieldName]),
'RSA-OAEP',
{md: forge.md.sha256.create(), mgf1: { md: forge.md.sha1.create() }},
)
);
}
});
next()
});
app.use(function(req, res, next) {
res.send(JSON.stringify(req.body));
console.info(`Sent response for ${req.url}`);
});
app.listen(port);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment