Last active
November 26, 2019 14:18
-
-
Save tlwr/7e9a5ae47e8ecd0b909eefb2a5b8fdaf to your computer and use it in GitHub Desktop.
CloudFront form field encryption
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
See index.js |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-----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 file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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