/** * Bcrypt * * @param string $password * @throws Exception\RuntimeException * @return string */ public function create($password) { if (empty($this->salt)) { $salt = Math::randBytes(self::MIN_SALT_SIZE); } else { $salt = $this->salt; } $salt64 = substr(str_replace('+', '.', base64_encode($salt)), 0, 22); /** * Check for security flaw in the bcrypt implementation used by crypt() * @see http://php.net/security/crypt_blowfish.php */ if (version_compare(PHP_VERSION, '5.3.7') >= 0) { $prefix = '$2y$'; } else { $prefix = '$2a$'; // check if the password contains 8-bit character if (preg_match('/[\\x80-\\xFF]/', $password)) { throw new Exception\RuntimeException('The bcrypt implementation used by PHP can contains a security flaw using password with 8-bit character. ' . 'We suggest to upgrade to PHP 5.3.7+ or use passwords with only 7-bit characters'); } } $hash = crypt($password, $prefix . $this->cost . '$' . $salt64); if (strlen($hash) <= 13) { throw new Exception\RuntimeException('Error during the bcrypt generation'); } return $hash; }
public function testRandBigInteger() { try { $math = new \Zend\Math\BigInteger(); } catch (\Zend\Math\Exception\ExceptionInterface $e) { if (strpos($e->getMessage(), 'big integer precision math support not detected') !== false) { $this->markTestSkipped($e->getMessage()); } else { throw $e; } } $math = new Math; $higher = '155172898181473697471232257763715539915724801966915404479707795314057629378541917580651227423698188993727816152646631438561595825688188889951272158842675419950341258706556549803580104870537681476726513255747040765857479291291572334510643245094715007229621094194349783925984760375594985848253359305585439638443'; $lower = '155172898181473697471232257763715539915724801966915404479707795314057629378541917580651227423698188993727816152646631438561595825688188889951272158842675419950341258706556549803580104870537681476726513255747040765857479291291572334510643245094715007229621094194349783925984760375594985848253359305585439638442'; $result = $math->rand($lower, $higher); $this->assertTrue(bccomp($result, $higher) !== '1'); $this->assertTrue(bccomp($result, $lower) !== '-1'); }
/** * Bcrypt * * @param string $password * @return string */ public function create($password) { if (empty($this->salt)) { $salt = Math::randBytes(self::MIN_SALT_SIZE, true); } else { $salt = $this->salt; } $salt64 = substr(str_replace('+', '.', base64_encode($salt)), 0, 22); $hash = crypt($password, '$2a$' . $this->cost . '$' . $salt64); if (strlen($hash) <= 13) { throw new Exception\RuntimeException('Error during the bcrypt generation'); } return $hash; }
/** * Encrypt then authenticate using HMAC * * @param string $data * @return string * @throws Exception\InvalidArgumentException */ public function encrypt($data) { if (empty($data)) { throw new Exception\InvalidArgumentException('The data to encrypt cannot be empty'); } if (empty($this->key)) { throw new Exception\InvalidArgumentException('No key specified for the encryption'); } if (empty($this->cipher)) { throw new Exception\InvalidArgumentException('No symmetric cipher specified'); } $keySize = $this->cipher->getKeySize(); // generate a random salt (IV) $this->cipher->setSalt(Math::randBytes($this->cipher->getSaltSize(), true)); // generate the encryption key and the HMAC key for the authentication $hash = Pbkdf2::calc(self::KEY_DERIV_HMAC, $this->getKey(), $this->cipher->getSalt(), $this->keyIteration, $keySize * 2); // set the encryption key $this->cipher->setKey(substr($hash, 0, $keySize)); // set the key for HMAC $keyHmac = substr($hash, $keySize); // encryption $ciphertext = $this->cipher->encrypt($data); // HMAC $hmac = Hmac::compute($keyHmac, $this->hash, $this->cipher->getAlgorithm() . $ciphertext); if (!$this->binaryOutput) { $ciphertext = base64_encode($ciphertext); } return $hmac . $ciphertext; }
/** * In the event a private number/key has not been set by the user, * or generated by ext/openssl, a best attempt will be made to * generate a random key. Having a random number generator installed * on linux/bsd is highly recommended! The alternative is not recommended * for production unless without any other option. * * @return string */ protected function generatePrivateKey() { $rand = $this->math->randBytes(strlen($this->getPrime()), true); return $rand; }