Beispiel #1
0
 /**
  * Creates a salted hash from a string.
  *
  *   @param string $str
  *     String to hash.
  *
  *   @return string
  *     Returns hashed string, or false on error.
  */
 public static function create($str)
 {
     switch (self::$_method) {
         case self::BCRYPT:
             $saltRnd = phpsecRand::str(22, self::$charsets['itoa64']);
             $salt = sprintf('$2a$%s$%s', self::$_bcrypt_cost, $saltRnd);
             $hash = crypt($str, $salt);
             break;
         case self::PBKDF2:
             $salt = phpsecRand::bytes(64);
             $hash = phpsecCrypt::pbkdf2($str, $salt, self::$_pbkdf2_c, self::$_pbkdf2_dkLen, self::$_pbkdf2_prf);
             $hash = sprintf('$pbkdf2$c=%s&dk=%s&f=%s$%s$%s', self::$_pbkdf2_c, self::$_pbkdf2_dkLen, self::$_pbkdf2_prf, base64_encode($hash), base64_encode($salt));
             break;
         case self::SHA256:
         case self::SHA512:
             $saltRnd = phpsecRand::str(16, self::$charsets['itoa64']);
             $salt = sprintf('%srounds=%s$%s', self::$_method, self::$_sha2_c, $saltRnd);
             $hash = crypt($str, $salt);
             break;
     }
     if (strlen($hash) > 13) {
         return $hash;
     }
     return false;
 }
Beispiel #2
0
 /**
  * Generate and save a one-time-token for a form. Used to protect against
  * CSRF attacks.
  *
  * @param string $name
  *   Name of the form to generate a token for.
  *
  * @param integer $ttl
  *   How long the token should be valid in seconds.
  *
  * @return string
  *   The token to supply with the form data.
  */
 public static function set($name, $ttl = 3600)
 {
     $token = phpsecRand::str(32);
     /* Save the token to the cahce. */
     phpsecCache::cacheSet('token-' . $name, $token, $ttl);
     return $token;
 }
Beispiel #3
0
 /**
  * Select a pre shared OTP from a list that a user can use.
  *
  * @param string $cardId
  *   Card ID to select a OTP from.
  *
  * @return integer
  *   OTP ID of a available OTP.
  */
 public static function select($cardId)
 {
     $card = self::load($cardId);
     $available = array_keys($card['usable']);
     $selected = phpsecRand::int(0, count($available) - 1);
     return $available[$selected];
 }
Beispiel #4
0
 /**
  * Verify Yubikey one time password against the Yubico servers.
  *
  * @param string $otp
  *   One time password to verify.
  *
  * @return boolean
  *   True on valid OTP, false on invalid. If this method returns false
  *   phpsecYubikey::$lastError will contain details.
  *
  * @see http://phpseclib.com/manual/yubikey/errors
  */
 public static function verify($otp)
 {
     if (self::$_clientId === null || self::$_clientSecret === null) {
         self::$lastError = 'YUBIKEY_CLIENT_DATA_NEEDED';
         return false;
     }
     if (!self::validOtp($otp)) {
         self::$lastError = 'YUBIKEY_INVALID_OTP';
         return false;
     }
     /* Setup the data needed to make the request. */
     $data['otp'] = $otp;
     $data['id'] = self::$_clientId;
     $data['nonce'] = phpsecRand::str(20);
     $data['timestamp'] = 1;
     $data['h'] = self::sign($data);
     /* Do the request. */
     $response = self::getResponse($data);
     if ($response === false) {
         self::$lastError = 'YUBIKEY_SERVER_ERROR';
         return false;
     }
     /* Check status of response. If not OK return false. */
     if ($response['status'] != 'OK') {
         switch ($response['status']) {
             case 'REPLAYED_OTP':
                 self::$lastError = 'YUBIKEY_SERVER_REPLAYED_OTP';
                 break;
             case 'REPLAYED_REQUEST':
                 self::$lastError = 'YUBIKEY_SERVER_REPLAYED_REQUEST';
                 break;
             case 'BAD_OTP':
                 self::$lastError = 'YUBIKEY_SERVER_BAD_OTP';
                 break;
             case 'NO_SUCH_CLIENT':
                 self::$lastError = 'YUBIKEY_SERVER_NO_SUCH_CLIENT';
                 break;
             case 'BAD_SIGNATURE':
                 self::$lastError = 'YUBIKEY_SERVER_BAD_SIGNATURE';
                 break;
             default:
                 self::$lastError = 'YUBIKEY_SERVER_SAYS_NO';
                 break;
         }
         return false;
     }
     /* If tokens don't match return false. */
     if ($response['otp'] != $otp) {
         self::$lastError = 'YUBIKEY_NO_MATCH';
         return false;
     }
     /* Sign the request to see if it matches signature from server. */
     $signature = self::sign($response);
     if ($signature !== $response['h']) {
         self::$lastError = 'YUBIKEY_BAD_SERVER_SIGNATURE';
         return false;
     }
     return true;
 }
Beispiel #5
0
 /**
  * Create a list of 64 pre shared one-time-passwords,
  * or a so called password card.
  *
  * This differs from phpsecOtp::generate() because passwords generated by
  * this function is saved permanent and can be validated on a later time.
  */
 public static function create($length = 6, $num = 32)
 {
     $card['list'] = array();
     for ($i = 0; $i < $num; $i++) {
         $card['list'][$i] = phpsecRand::str($length);
         $card['usable'][$i] = true;
     }
     $card = self::save($card);
     return $card['id'];
 }
Beispiel #6
0
 /**
  * Generate a one-time-password (OTP). The password is only valid for a given time,
  * and must be delivered to the user instantly. The password is also only valid
  * for the current session.
  *
  * @param string $action
  *   The action to generate a OTP for. This should be as specific as possible.
  *   Used to ensure that the OTP is used for the intended action.
  *
  * @param array $data
  *   Optional array of data that belongs to $action. Used to ensure that the action
  *   is performed with the same data as when the OTP was generated.
  *
  * @param integer $length
  *   OTP length.
  *
  * @param integer $ttl
  *   Time to live for the OTP. In seconds.
  *
  * @return string
  *   One time password that should be delivered to the user by for example email or SMS.
  *
  */
 public static function generate($action, $data = '', $length = 6, $ttl = 480)
 {
     $pw = phpsecRand::str($length);
     $otp['pw'] = phpsecHash::create($pw);
     if ($data !== null) {
         $otp['data'] = phpsecHash::create(serialize($data));
     } else {
         $otp['data'] = $data;
     }
     phpsecCache::cacheSet('otp-' . $action, $otp, $ttl);
     return $pw;
 }
Beispiel #7
0
 /**
  * Create a hashed version of a password, safe for storage in a database.
  * This function return a json encoded array that can be stored directly
  * into a database. The array has the following layout:
  * array(
  *   'hash'      => The hash created from the password and a salt.
  *   'salt'      => The salt that was used along with the password to create the hash.
  *   'algo'      => The hashing algorithm used.
  * )
  *
  * @param string $password
  *   The password to hash.
  *
  * @return string
  *   Returns a json encoded array containing the password hash, salt and
  *   some meta data.
  */
 public static function hash($password)
 {
     $salt = phpsecRand::bytes(64);
     switch (self::$_method) {
         case self::phpsecPw_PBKDF2:
             $hash = phpsecCrypt::pbkdf2($password, $salt, self::$_pbkdf2_c, self::$_pbkdf2_dkLen, self::$_pbkdf2_prf);
             /* phpsecCrypt::pbkdf2() returns a binary string. So let's base64 encode it.*/
             $hash = base64_encode($hash);
             /* We append the iteration count, derived key length and PRF as we need this later. */
             $algo = 'pbkdf2:' . self::$_pbkdf2_c . ':' . self::$_pbkdf2_dkLen . ':' . self::$_pbkdf2_prf;
             break;
         default:
             $injected = self::inject($password, $salt);
             $hash = hash(self::$_method, $injected);
             $algo = self::$_method;
     }
     $return = array('hash' => $hash, 'salt' => base64_encode($salt), 'algo' => $algo);
     return json_encode($return);
 }
 /**
  * Encrypt data returning a JSON encoded array safe for storage in a database
  * or file. The array has the following structure before it is encoded:
  * array(
  *   'cdata' => 'Encrypted data, Base 64 encoded',
  *   'iv'    => 'Base64 encoded IV',
  *   'algo'  => 'Algorythm used',
  *   'mode'  => 'Mode used',
  *   'mac'   => 'Message Authentication Code'
  * )
  *
  * @param mixed $data
  *   Data to encrypt.
  *
  * @param string $key
  *   Key to encrypt data with.
  *
  * @return string
  *   Serialized array containing the encrypted data along with some meta data.
  */
 public static function encrypt($data, $key)
 {
     $td = mcrypt_module_open(self::$_algo, '', self::$_mode, '');
     /* Check key size. */
     $keySize = strlen($key);
     $keySizes = mcrypt_enc_get_supported_key_sizes($td);
     if (count($keySizes) > 0) {
         /* Encryption method requires a specific key size. */
         if (!in_array($keySize, $keySizes)) {
             phpsec::error('Key is out of range. Should be one of: ' . var_export($keySizes, 1));
             return false;
         }
     } else {
         /* No spsecific size is needed. */
         if ($keySize == 0 || $keySize > mcrypt_enc_get_key_size($td)) {
             phpsec::error('Key is out of range. Should be: 1 - ' . mcrypt_enc_get_key_size($td) . ' bytes.');
             return false;
         }
     }
     /* Create IV. */
     $iv = phpsecRand::bytes(mcrypt_enc_get_iv_size($td));
     /* Init mcrypt. */
     mcrypt_generic_init($td, $key, $iv);
     /* Prepeare the array with data. */
     $serializedData = serialize($data);
     /* Add padding if enabled. */
     if (self::$_padding === true) {
         $block = mcrypt_enc_get_block_size($td);
         $serializedData = self::pad($block, $serializedData);
     }
     $encrypted['algo'] = self::$_algo;
     /* Algorithm used to encrypt. */
     $encrypted['mode'] = self::$_mode;
     /* Algorithm mode. */
     $encrypted['iv'] = base64_encode($iv);
     /* Initialization vector, just a bunch of randomness. */
     $encrypted['cdata'] = base64_encode(mcrypt_generic($td, $serializedData));
     /* The encrypted data. */
     $encrypted['mac'] = base64_encode(self::pbkdf2($encrypted['cdata'], $key, 1000, 32));
     return json_encode($encrypted);
 }
Beispiel #9
0
 /**
  * Provides a random 32 bit number
  * if openssl is available, it is cryptographically secure. Otherwise all available entropy is gathered.
  * @return number
  */
 public static function random()
 {
     //If openssl is present, use that to generate random.
     if (function_exists("openssl_random_pseudo_bytes") && FALSE) {
         $random32bit = (int) hexdec(bin2hex(openssl_random_pseudo_bytes(64)));
     } else {
         if (self::$randomSeed === null) {
             $entropy = 1;
             if (function_exists("posix_getpid")) {
                 $entropy *= posix_getpid();
             }
             if (function_exists("memory_get_usage")) {
                 $entropy *= memory_get_usage();
             }
             list($usec, $sec) = explode(" ", microtime());
             $usec *= 1000000;
             $entropy *= $usec;
             self::$randomSeed = $entropy;
             mt_srand(self::$randomSeed);
         }
         $random32bit = mt_rand();
     }
     return $random32bit;
 }
Beispiel #10
0
 public function generate_unique_sequence($entropy = 100)
 {
     require_once 'lib/phpsec/phpsec/phpsec.rand.php';
     return base64_encode(phpsecRand::bytes($entropy));
 }
Beispiel #11
0
	private function generate_provisional_password()
	{
		global $tikilib;
		require_once 'lib/phpsec/phpsec/phpsec.rand.php';

		$site_hash = $tikilib->get_site_hash();

		$random_value = phpsecRand::bytes(40);

		return base64_encode(sha1($random_value . $site_hash, true));
	}
Beispiel #12
0
 /**
  * Returns a unique identifier in the format spsecified in
  * OpenID Authentication 2.0 protocol.
  * For example: 2005-05-15T17:11:51ZUNIQUE
  * This function is used to generate all unique tokens used by
  * phpSec.
  * @see http://openid.net/specs/openid-authentication-2_0.html
  *
  * @param integer $length
  *   The total length of the uid. Must be above 25.
  */
 public static function genUid($length = 50)
 {
     if ($length < 25) {
         self::error('Length must be longer than 25');
         return false;
     }
     $timeStamp = gmdate('Y-m-d\\TH:i:se');
     $randLength = $length - strlen($timeStamp);
     return $timeStamp . phpsecRand::str($randLength);
 }
Beispiel #13
0
 /**
  * Set the cookie with the secret.
  *
  * @return true
  */
 private static function setSecret()
 {
     self::$_secret = phpsecRand::bytes(32);
     $cookieParam = session_get_cookie_params();
     setcookie(self::$_keyCookie, base64_encode(self::$_secret), $cookieParam['lifetime'], $cookieParam['path'], $cookieParam['domain'], $cookieParam['secure'], $cookieParam['httponly']);
     return true;
 }
Beispiel #14
0
	public function get_site_hash()
	{
		global $prefs;

		if (! isset($prefs['internal_site_hash'])) {
			require_once 'lib/phpsec/phpsec/phpsec.rand.php';

			$hash = base64_encode(phpsecRand::bytes(100));

			$this->set_preference('internal_site_hash', $hash);
		}

		return $prefs['internal_site_hash'];
	}