Skip to content

Instantly share code, notes, and snippets.

@codebudo
Last active March 24, 2018 21:38
Show Gist options
  • Select an option

  • Save codebudo/e7f81fff9ed8cd64e8e47934758b42f4 to your computer and use it in GitHub Desktop.

Select an option

Save codebudo/e7f81fff9ed8cd64e8e47934758b42f4 to your computer and use it in GitHub Desktop.
It's possible to alter encrypted data if you know something about the underlying plaintext.
var crypto = require('crypto');
var iv = Buffer.from('0000000000000000000000==', 'base64');
var key = Buffer.from('ffffffffffffffffffffffffffffffff');
// aes-256-gcm or aes-256-ctr
var encrypt = crypto.createCipheriv('aes-256-ctr', key, iv);
var decrypt = crypto.createDecipheriv('aes-256-ctr', key, iv);
var plaintext = 'hello world';
console.log(plaintext, 'plaintext')
// encrypt plaintext
var ciphertext = encrypt.update(plaintext);
encrypt.final();
console.log(ciphertext.toString('hex'), 'encryption of plaintext');
// encrypted ciphertext is <Buffer 2b e3 9e bf 8a 38 9f 8f 34 6e 52>
// replace 'hello ' with 'hacked'
var hello = Buffer.from('hello 00000');
var replace = Buffer.from('hacked00000');
// xor the ciphertext with the known plaintext to expose the key fragment
var t = xor(ciphertext, hello);
// then xor the exposed key with the replacement text
var hacked = xor(t, replace);
// Viola! hacked ciphertext
console.log( hacked.toString('hex'), 'altered ciphertext' );
// decrypt tampered ciphertext
var tamperedplaintext = decrypt.update(hacked);
decrypt.final(); // aes-256-gcm will authenticate here
console.log(tamperedplaintext.toString('ascii'), 'tampered plaintext');
// helper function
function xor (a, b) {
var length = Math.max(a.length, b.length)
var buffer = Buffer.allocUnsafe(length)
for (var i = 0; i < length; ++i) {
buffer[i] = a[i] ^ b[i]
}
return buffer
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment