function editAES128CTR($ciphertext, $key, $nonce = "", $offset, $newtext) { $newLen = strlen($newtext); // really dirty - I could calculate block specific keys, but I don't really have to for this. $plaintext = encryptAES128CTR($ciphertext, $key, $nonce); $plainLen = strlen($plaintext); $newPlaintext = ''; if ($offset > 0) { $newPlaintext = substr($plaintext, 0, $offset); } $newPlaintext .= $newtext; if ($newLen + $offset < $plainLen) { $newPlaintext .= substr($plaintext, $newLen + $offset); } return encryptAES128CTR($newPlaintext, $key, $nonce); }
* Most modern cryptography relies on CTR mode to adapt block ciphers into stream ciphers, because most of what we want to encrypt is better described as a stream than as a sequence of blocks. Daniel Bernstein once quipped to Phil Rogaway that good cryptosystems don't need the "decrypt" transforms. Constructions like CTR are what he was talking about. */ if (PHP_INT_SIZE < 8) { throw new Exception('64 bit PHP required!'); } // pull in previous functions to do single blocks of AES require_once '../01-basics/07-aes-in-ecb-mode.php'; function encryptAES128CTR($data, $key, $nonce = "") { $blocks = str_split($data, 16); $counter = unpack('V4', $nonce); foreach ($blocks as &$block) { $block ^= _encryptAES128ECB(pack('V4', $counter[1], $counter[2], $counter[3], $counter[4]), $key); // Because we don't have unsigned 64 bit numbers in PHP... $counter[3] = ($carry = $counter[3] + 1) & 0xffffffff; $counter[4] = ($carry >> 32) + $counter[4] & 0xffffffff; } return implode($blocks); } // don't output if we're included into another script. if (!debug_backtrace()) { $ciphertext = base64_decode('L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ=='); $key = 'YELLOW SUBMARINE'; $plaintext = encryptAES128CTR($ciphertext, $key); $homebrewCipher = encryptAES128CTR($plaintext, $key); print "Sanity check:\n"; $sanity = $ciphertext === $homebrewCipher; print $sanity ? "Success!\n\n" : "Failure :(\n\n"; print "Decrypted data:\n"; print "{$plaintext}\n"; }
function isAdmin($query, $key, $iv) { $data = encryptAES128CTR($query, $key, $iv); return strpos($data, ';admin=true;') !== false; }