<?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);
function urlsafe_b64encode($string) {
$data = base64_encode($string);
$data = str_replace(array('+','/','='),array('-','_',''),$data);
return $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 = '';
$record = '';
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
);
$record .= chr($block_index) . urlsafe_b64encode($last_block) . "\n";
// T = T(1) | T(2) | T(3) | ... | T(N)
$t .= $last_block;
}
return $record;
// ORM = first L octets of T
$orm = substr($t, 0, $length);
if ($orm === FALSE) {
throw new CannotPerformOperationException();
}
return $orm;
}
?>
preferences:
36.74 ms | 402 KiB | 5 Q