Esempio n. 1
0
 /**
  * Returns the public key's fingerprint
  *
  * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is
  * no public key currently loaded, false is returned.
  * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716)
  *
  * @access public
  * @param String $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned
  * for invalid values.
  */
 public function getPublicKeyFingerprint($algorithm = 'md5')
 {
     if (empty($this->modulus) || empty($this->publicExponent)) {
         return false;
     }
     $modulus = $this->modulus->toBytes(true);
     $publicExponent = $this->publicExponent->toBytes(true);
     $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
     switch ($algorithm) {
         case 'sha256':
             $hash = new Hash('sha256');
             $base = base64_encode($hash->hash($RSAPublicKey));
             return substr($base, 0, strlen($base) - 1);
         case 'md5':
             return substr(chunk_split(md5($RSAPublicKey), 2, ':'), 0, -1);
         default:
             return false;
     }
 }
Esempio n. 2
0
 /**
  * @brief Legacy static call wrapper
  *
  * Not to be called directly. Rather use Hash::<algo>(<string>>)
  *
  * @param String $algo Algorithm
  * @param Array $args The arguments
  * @return String The hash
  */
 public function __call($algo, $args)
 {
     $ha = new Hash($algo);
     return $ha->hash($args[0]);
 }
Esempio n. 3
0
 /**
  * Sets the password.
  *
  * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
  *     {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1:
  *         $hash, $salt, $count, $dkLen
  *
  *         Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php
  *
  * @see      Crypt/Hash.php
  *
  * @param String $password
  * @param        optional String $method
  *
  * @return Boolean
  * @access   public
  * @internal Could, but not must, extend by the child Crypt_* class
  */
 function setPassword($password, $method = 'pbkdf2')
 {
     $key = '';
     switch ($method) {
         default:
             // 'pbkdf2' or 'pbkdf1'
             $func_args = func_get_args();
             // Hash function
             $hash = isset($func_args[2]) ? $func_args[2] : 'sha1';
             // WPA and WPA2 use the SSID as the salt
             $salt = isset($func_args[3]) ? $func_args[3] : $this->password_default_salt;
             // RFC2898#section-4.2 uses 1,000 iterations by default
             // WPA and WPA2 use 4,096.
             $count = isset($func_args[4]) ? $func_args[4] : 1000;
             // Keylength
             if (isset($func_args[5])) {
                 $dkLen = $func_args[5];
             } else {
                 $dkLen = $method == 'pbkdf1' ? 2 * $this->password_key_size : $this->password_key_size;
             }
             switch (true) {
                 case $method == 'pbkdf1':
                     $hashObj = new Hash();
                     $hashObj->setHash($hash);
                     if ($dkLen > $hashObj->getLength()) {
                         user_error('Derived key too long');
                         return false;
                     }
                     $t = $password . $salt;
                     for ($i = 0; $i < $count; ++$i) {
                         $t = $hashObj->hash($t);
                     }
                     $key = substr($t, 0, $dkLen);
                     $this->setKey(substr($key, 0, $dkLen >> 1));
                     $this->setIV(substr($key, $dkLen >> 1));
                     return true;
                     // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable
                 // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable
                 case !function_exists('hash_pbkdf2'):
                 case !function_exists('hash_algos'):
                 case !in_array($hash, hash_algos()):
                     $i = 1;
                     while (strlen($key) < $dkLen) {
                         $hmac = new Hash();
                         $hmac->setHash($hash);
                         $hmac->setKey($password);
                         $f = $u = $hmac->hash($salt . pack('N', $i++));
                         for ($j = 2; $j <= $count; ++$j) {
                             $u = $hmac->hash($u);
                             $f ^= $u;
                         }
                         $key .= $f;
                     }
                     $key = substr($key, 0, $dkLen);
                     break;
                 default:
                     $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true);
             }
     }
     $this->setKey($key);
     return true;
 }
Esempio n. 4
0
 /**
  * Convert a private key to the appropriate format.
  *
  * @access private
  * @see setPrivateKeyFormat()
  * @param String $RSAPrivateKey
  * @return String
  */
 function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
 {
     $num_primes = count($primes);
     $raw = array('version' => $num_primes == 2 ? chr(0) : chr(1), 'modulus' => $n->toBytes(true), 'publicExponent' => $e->toBytes(true), 'privateExponent' => $d->toBytes(true), 'prime1' => $primes[1]->toBytes(true), 'prime2' => $primes[2]->toBytes(true), 'exponent1' => $exponents[1]->toBytes(true), 'exponent2' => $exponents[2]->toBytes(true), 'coefficient' => $coefficients[2]->toBytes(true));
     // if the format in question does not support multi-prime rsa and multi-prime rsa was used,
     // call _convertPublicKey() instead.
     switch ($this->privateKeyFormat) {
         case CRYPT_RSA_PRIVATE_FORMAT_XML:
             if ($num_primes != 2) {
                 return false;
             }
             return "<RSAKeyValue>\r\n" . '  <Modulus>' . base64_encode($raw['modulus']) . "</Modulus>\r\n" . '  <Exponent>' . base64_encode($raw['publicExponent']) . "</Exponent>\r\n" . '  <P>' . base64_encode($raw['prime1']) . "</P>\r\n" . '  <Q>' . base64_encode($raw['prime2']) . "</Q>\r\n" . '  <DP>' . base64_encode($raw['exponent1']) . "</DP>\r\n" . '  <DQ>' . base64_encode($raw['exponent2']) . "</DQ>\r\n" . '  <InverseQ>' . base64_encode($raw['coefficient']) . "</InverseQ>\r\n" . '  <D>' . base64_encode($raw['privateExponent']) . "</D>\r\n" . '</RSAKeyValue>';
             break;
         case CRYPT_RSA_PRIVATE_FORMAT_PUTTY:
             if ($num_primes != 2) {
                 return false;
             }
             $key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
             $encryption = !empty($this->password) || is_string($this->password) ? 'aes256-cbc' : 'none';
             $key .= $encryption;
             $key .= "\r\nComment: " . $this->comment . "\r\n";
             $public = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']);
             $source = pack('Na*Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($encryption), $encryption, strlen($this->comment), $this->comment, strlen($public), $public);
             $public = base64_encode($public);
             $key .= "Public-Lines: " . (strlen($public) + 32 >> 6) . "\r\n";
             $key .= chunk_split($public, 64);
             $private = pack('Na*Na*Na*Na*', strlen($raw['privateExponent']), $raw['privateExponent'], strlen($raw['prime1']), $raw['prime1'], strlen($raw['prime2']), $raw['prime2'], strlen($raw['coefficient']), $raw['coefficient']);
             if (empty($this->password) && !is_string($this->password)) {
                 $source .= pack('Na*', strlen($private), $private);
                 $hashkey = 'putty-private-key-file-mac-key';
             } else {
                 $private .= crypt_random_string(16 - (strlen($private) & 15));
                 $source .= pack('Na*', strlen($private), $private);
                 $sequence = 0;
                 $symkey = '';
                 while (strlen($symkey) < 32) {
                     $temp = pack('Na*', $sequence++, $this->password);
                     $symkey .= pack('H*', sha1($temp));
                 }
                 $symkey = substr($symkey, 0, 32);
                 $crypto = new AES();
                 $crypto->setKey($symkey);
                 $crypto->disablePadding();
                 $private = $crypto->encrypt($private);
                 $hashkey = 'putty-private-key-file-mac-key' . $this->password;
             }
             $private = base64_encode($private);
             $key .= 'Private-Lines: ' . (strlen($private) + 32 >> 6) . "\r\n";
             $key .= chunk_split($private, 64);
             $hash = new Hash('sha1');
             $hash->setKey(pack('H*', sha1($hashkey)));
             $key .= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";
             return $key;
         default:
             // eg. CRYPT_RSA_PRIVATE_FORMAT_PKCS1
             $components = array();
             foreach ($raw as $name => $value) {
                 $components[$name] = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value);
             }
             $RSAPrivateKey = implode('', $components);
             if ($num_primes > 2) {
                 $OtherPrimeInfos = '';
                 for ($i = 3; $i <= $num_primes; $i++) {
                     // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
                     //
                     // OtherPrimeInfo ::= SEQUENCE {
                     //     prime             INTEGER,  -- ri
                     //     exponent          INTEGER,  -- di
                     //     coefficient       INTEGER   -- ti
                     // }
                     $OtherPrimeInfo = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
                     $OtherPrimeInfo .= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
                     $OtherPrimeInfo .= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
                     $OtherPrimeInfos .= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
                 }
                 $RSAPrivateKey .= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
             }
             $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
             if (!empty($this->password) || is_string($this->password)) {
                 $iv = crypt_random_string(8);
                 $symkey = pack('H*', md5($this->password . $iv));
                 // symkey is short for symmetric key
                 $symkey .= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
                 $des = new TripleDES();
                 $des->setKey($symkey);
                 $des->setIV($iv);
                 $iv = strtoupper(bin2hex($iv));
                 $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" . "Proc-Type: 4,ENCRYPTED\r\n" . "DEK-Info: DES-EDE3-CBC,{$iv}\r\n" . "\r\n" . chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) . '-----END RSA PRIVATE KEY-----';
             } else {
                 $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" . chunk_split(base64_encode($RSAPrivateKey), 64) . '-----END RSA PRIVATE KEY-----';
             }
             return $RSAPrivateKey;
     }
 }
Esempio n. 5
0
 /**
  * Sets the password.
  *
  * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
  *     {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
  *         $hash, $salt, $method
  *     Set $dkLen by calling setKeyLength()
  *
  * @param String $password
  * @param optional String $method
  * @access public
  */
 function setPassword($password, $method = 'pbkdf2')
 {
     $key = '';
     switch ($method) {
         default:
             // 'pbkdf2'
             list(, , $hash, $salt, $count) = func_get_args();
             if (!isset($hash)) {
                 $hash = 'sha1';
             }
             // WPA and WPA2 use the SSID as the salt
             if (!isset($salt)) {
                 $salt = 'phpseclib';
             }
             // RFC2898#section-4.2 uses 1,000 iterations by default
             // WPA and WPA2 use 4,096.
             if (!isset($count)) {
                 $count = 1000;
             }
             $i = 1;
             while (strlen($key) < $this->key_size) {
                 // $dkLen == $this->key_size
                 //$dk.= $this->_pbkdf($password, $salt, $count, $i++);
                 $hmac = new Hash();
                 $hmac->setHash($hash);
                 $hmac->setKey($password);
                 $f = $u = $hmac->hash($salt . pack('N', $i++));
                 for ($j = 2; $j <= $count; $j++) {
                     $u = $hmac->hash($u);
                     $f ^= $u;
                 }
                 $key .= $f;
             }
     }
     $this->setKey(substr($key, 0, $this->key_size));
 }
Esempio n. 6
0
 /**
  * @brief Test a password for a username.
  * Returns true if the password is a valid authentication token for
  * the specified user.
  *
  * @param string $username The username to match against
  * @param string $password The password to match with
  * @return bool True on success.
  */
 public function validateCredentials($username, $password, $ext = false)
 {
     $db = new DatabaseConnection();
     try {
         $userrecord = $db->getSingleRow("SELECT * FROM " . LEPTON_DB_PREFIX . "users WHERE username=%s", $username);
         if ($userrecord) {
             try {
                 list($ha, $rounds, $us, $hash) = $this->getHashComponents($userrecord['password']);
                 $ps = $us . $password;
                 logger::debug("Hash algorithm: %s (salt=%s)", $ha, $us);
             } catch (SecurityException $e) {
                 // Fall back on MD5 or defined algorithm
                 $ha = config::get('lepton.user.hashalgorithm', 'md5');
                 // Grab the salt, concatenate the password and the salt,
                 // and hash it with the selected hashing algorithm.
                 $us = $userrecord['salt'];
                 $hash = $userrecord['password'];
                 $ps = $password . $us;
                 $rounds = 1;
                 logger::debug("Hash algorithm: %s (salt=%s) [VIA FALLBACK!]", $ha, $us);
             }
             $oha = new Hash($ha);
             // Iterate specified number of rounds
             for ($n = 0; $n < $rounds; $n++) {
                 $ps = $oha->hash($ps);
             }
             $hp = $ps;
             // Check the hash against the one on file
             if ($hp == $hash) {
                 $this->userid = $userrecord['id'];
                 return true;
             }
             return false;
         }
     } catch (Exception $e) {
         throw $e;
         // TODO: Handle exception
     }
 }
Esempio n. 7
0
 /**
  * Sets the password.
  *
  * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
  *     {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
  *         $hash, $salt, $method
  *
  * @param String $password
  * @param optional String $method
  * @access public
  */
 function setPassword($password, $method = 'pbkdf2')
 {
     $key = '';
     switch ($method) {
         default:
             // 'pbkdf2'
             list(, , $hash, $salt, $count) = func_get_args();
             if (!isset($hash)) {
                 $hash = 'sha1';
             }
             // WPA and WPA2 use the SSID as the salt
             if (!isset($salt)) {
                 $salt = 'phpseclib';
             }
             // RFC2898#section-4.2 uses 1,000 iterations by default
             // WPA and WPA2 use 4,096.
             if (!isset($count)) {
                 $count = 1000;
             }
             if (!class_exists('Crypt_Hash')) {
                 require_once 'Crypt/Hash.php';
             }
             $i = 1;
             while (strlen($key) < 24) {
                 // $dkLen == 24
                 $hmac = new Hash();
                 $hmac->setHash($hash);
                 $hmac->setKey($password);
                 $f = $u = $hmac->hash($salt . pack('N', $i++));
                 for ($j = 2; $j <= $count; $j++) {
                     $u = $hmac->hash($u);
                     $f ^= $u;
                 }
                 $key .= $f;
             }
     }
     $this->setKey($key);
 }
Esempio n. 8
0
<?php

include '../phpseclib/phpseclib/Crypt/Hash.php';
include 'Hash.php';
$text_to_hash = 'This is something secret';
$key = 'IVxSISQCUnFoEfPU';
echo 'Text to hash: ' . $text_to_hash . "\r\n";
echo 'MAC key: ' . $key . "\r\n";
$hashes_array = hash_algos();
foreach ($hashes_array as $hash_element) {
    $hash = new Hash($hash_element);
    echo $hash_element . ': ' . $hash->hash($text_to_hash) . "\r\n";
    echo $hash_element . ' MAC: ';
    $hash->setKey($key);
    echo $hash->hash($text_to_hash) . "\r\n";
}
Esempio n. 9
0
 /**
  * Validates a message signature and returns the signed message.
  *
  * @param string $message The signed message JSON string.
  * @param string $key The signing key used with the message.
  * @param string $hashKey The key to hash the key with.
  * @return string A string returning the output of the signed message.
  * @throws Exceptions\InvalidTypeException
  * @throws Exceptions\SignatureException
  */
 public static function verifyMessage($message, $key, $hashKey = '')
 {
     # Test the message and key for string validity.
     Helpers::isString($message, 'Encryption', 'verifyMessage');
     Helpers::isString($key, 'Encryption', 'verifyMessage');
     Helpers::isString($hashKey, 'Encryption', 'verifyMessage');
     # Create a special hashed key for encryption.
     $key = Hash::hash($key, $hashKey, Constants::AUTH_KEYBYTES);
     # Decode the message from JSON.
     $message = base64_decode(json_decode($message, true));
     if (\Sodium\crypto_auth_verify(Helpers::hex2bin($message['mac']), $message['msg'], $key)) {
         \Sodium\memzero($key);
         return $message['msg'];
     } else {
         \Sodium\memzero($key);
         throw new Exceptions\SignatureException('Signature for message invalid.');
     }
 }