<?php
const CIPHER = MCRYPT_RIJNDAEL_128;
const KEY_BYTE_SIZE = 16;
const CIPHER_MODE = 'cbc';
const HASH_FUNCTION = 'sha256';
const MAC_BYTE_SIZE = 32;
const ENCRYPTION_INFO = 'PIPS|KeyForEncryption';
const AUTHENTICATION_INFO = 'PIPS|KeyForAuthentication';
$key = base64_decode('wdmd3XIhnOAelom4Y8yPbw==');
$ekey = HKDF(HASH_FUNCTION, $key, KEY_BYTE_SIZE, ENCRYPTION_INFO);
//print "$ekey\n";
//print urlsafe_b64encode($ekey);
//$ivsize = mcrypt_get_iv_size(CIPHER, CIPHER_MODE);
//if ($ivsize === FALSE || $ivsize <= 0) {
// throw new CannotPerformOperationException();
//}
$ivsize= 16;
$iv = SecureRandom($ivsize);
print PlainEncrypt('It is a kitten', 'fish', 'fry');
function urlsafe_b64encode($string) {
$data = base64_encode($string);
$data = str_replace(array('+','/','='),array('-','_',''),$data);
return $data;
}
function urlsafe_b64decode($string) {
$data = str_replace(array('-','_'),array('+','/'),$string);
return base64_decode($data);
}
function HKDF($hash, $ikm, $length, $info = '', $salt = NULL)
{
// Find the correct digest length as quickly as we can.
$digest_length = MAC_BYTE_SIZE;
if ($hash != HASH_FUNCTION) {
$digest_length = strlen(hash_hmac($hash, '', '', true));
}
// Sanity-check the desired output length.
if (empty($length) || !is_int($length) ||
$length < 0 || $length > 255 * $digest_length) {
return CannotPerformOperationException();
}
// "if [salt] not provided, is set to a string of HashLen zeroes."
if (is_null($salt)) {
$salt = str_repeat("\x00", $digest_length);
}
// HKDF-Extract:
// PRK = HMAC-Hash(salt, IKM)
// The salt is the HMAC key.
$prk = hash_hmac($hash, $ikm, $salt, true);
// HKDF-Expand:
// This check is useless, but it serves as a reminder to the spec.
if (strlen($prk) < $digest_length) {
throw new CannotPerformOperationException();
}
// T(0) = ''
$t = '';
$last_block = '';
for ($block_index = 1; strlen($t) < $length; $block_index++) {
// T(i) = HMAC-Hash(PRK, T(i-1) | info | 0x??)
$last_block = hash_hmac(
$hash,
$last_block . $info . chr($block_index),
$prk,
true
);
// T = T(1) | T(2) | T(3) | ... | T(N)
$t .= $last_block;
}
// ORM = first L octets of T
$orm = substr($t, 0, $length);
if ($orm === FALSE) {
throw new CannotPerformOperationException();
}
return $orm;
}
function SecureRandom($octets)
{
return urlsafe_b64decode('FSDTs5UoRN07CAeB84KVIw');
$random = mcrypt_create_iv($octets, MCRYPT_DEV_URANDOM);
if ($random === FALSE) {
throw new CannotPerformOperationException();
} else {
return $random;
}
}
function PlainEncrypt($plaintext, $key, $iv)
{
$crypt = mcrypt_module_open(CIPHER, "", CIPHER_MODE, "");
if ($crypt === FALSE) {
throw new CannotPerformOperationException();
}
// Pad the plaintext to a multiple of the block size.
$block = mcrypt_enc_get_block_size($crypt);
$pad = $block - (strlen($plaintext) % $block);
$plaintext .= str_repeat(chr($pad), $pad);
$ret = mcrypt_generic_init($crypt, $key, $iv);
if ($ret !== 0) {
throw new CannotPerformOperationException();
}
$ciphertext = mcrypt_generic($crypt, $plaintext);
$ret = mcrypt_generic_deinit($crypt);
if ($ret !== TRUE) {
throw new CannotPerformOperationException();
}
$ret = mcrypt_module_close($crypt);
if ($ret !== TRUE) {
throw new CannotPerformOperationException();
}
return $ciphertext;
}
?>
preferences:
51.67 ms | 410 KiB | 5 Q