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";
}
Exemplo n.º 3
0
function isAdmin($query, $key, $iv)
{
    $data = encryptAES128CTR($query, $key, $iv);
    return strpos($data, ';admin=true;') !== false;
}