/** * Internal function used to build the actual hash. * * @param string $input Data to hash * @param string $password Password to use in HMAC call * @param integer $cost Number of iterations to use * @param string|null $salt Initialization vector to use in HMAC calls * @return string */ private static function build($input, $password, $cost, $salt = null) { // Generate salt if needed $salt = $salt === null ? Random::bytes(16) : $salt; // Verify and normalize cost value $cost = self::cost($cost); // Create key to use for hmac operations $key = \hash_hmac(self::ALGO, $salt, $password, true); // Perform hash iterations. Get a 32 byte output value $hash = self::ihmac($input, $key, $cost, self::ALGO); // Return the salt + cost blob + hmac return $salt . self::costHash($cost, $salt, $password) . $hash; }
/** * Compares two strings in constant time. Strings are hashed before * comparison so information is not leaked when strings are not of * equal length. * * @param string $known The string of known length to compare against * @param string $given The string that the user can control * * @return bool */ public static function equal($known, $given) { // We hash the 2 inputs at this point because hash_equals is still // vulnerable to timing attacks when the inputs have different sizes. // Inputs are also cast to string like in symfony stringutils. $nonce = Random::bytes(32); $known = \hash_hmac('sha256', (string) $known, $nonce, true); $given = \hash_hmac('sha256', (string) $given, $nonce, true); if (\function_exists('hash_equals')) { return \hash_equals($known, $given); // @codeCoverageIgnore } return self::strcmp($known, $given); }
/** * Encrypt plaintext * * @param string $plaintext Plaintext string to encrypt * @param string $password Key used to encrypt data * @param int $cost Number of HMAC iterations to perform on key * @param string $cipher Mcrypt cipher * @param string $mode Mcrypt mode * @param string $algo Hashing algorithm to use for internal operations * * @return string */ public static function encrypt($plaintext, $password, $cost = 0, $cipher = MCRYPT_RIJNDAEL_128, $mode = MCRYPT_MODE_CBC, $algo = 'sha256') { // Pad the input string to a multiple of block size $padded = Pkcs7::pad($plaintext, \mcrypt_get_block_size($cipher, $mode)); // Generate IV of appropriate size $iv = Random::bytes(\mcrypt_get_iv_size($cipher, $mode)); // Derive key from password $key = self::key($password, $iv, $cost, $cipher, $mode, $algo); // Encrypt the plaintext $message = \mcrypt_encrypt($cipher, $key, $padded, $mode, $iv); // Create the cypher text prefix (iv + checksum) $prefix = $iv . self::checksum($message, $iv, $key, $cipher, $mode, $algo); // Return prefix + cyphertext return $prefix . $message; }
public function testLength() { $this->assertSame(32, strlen(Random::bytes(32))); }
<div class="col-sm-12"> <h4>PHP Implementation Tests</h4> <?php $my_random_boolean = Random::boolean() ? 1 : 0; $result_true = 0; $result_false = 0; for ($i = 1; $i <= 100; $i++) { if (Random::boolean()) { $result_true++; } else { $result_false++; } } $my_random_bytes = bin2hex(Random::bytes(10)); $my_random_float = Random::float(); $my_random_integer = Random::int(0, PHP_INT_MAX); $my_random_integer_2 = Random::int(1, 100); $my_random_string = Random::string(20); $my_random_string_2 = Random::string(20, "!\"#\$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"); ?> <table class="table table-bordered" style="table-layout: fixed; word-wrap: break-word;"> <tbody> <tr> <td style="width: 50%;"><pre><code>$my_random_boolean = Random::boolean() ? 1 : 0;</code></pre></td> <td><?php echo $my_random_boolean; ?> </td> </tr>
public function testLength() { $this->assertEquals(10, strlen(Random::bytes(10))); }
/** * Encrypt plaintext * * @param string $plaintext Plaintext string to encrypt. * @param string $password Password used to encrypt data. * @param int $cost Number of HMAC iterations to perform on key * * @return string */ public static function encrypt($plaintext, $password, $cost = 0) { // Generate IV of appropriate size. $iv = Random::bytes(self::IVSIZE); // Derive key from password $key = self::key($password, $iv, $cost, self::RIJNDA, self::mode()); // Encrypt the plaintext $message = \openssl_encrypt($plaintext, static::CIPHER, $key, 1, $iv); // Create the cypher text prefix (iv + checksum) $prefix = $iv . self::checksum($message, $iv, $key, self::RIJNDA, self::mode()); // Return prefix + cyphertext return $prefix . $message; }