diff options
author | Olav Morken <olav.morken@uninett.no> | 2011-10-28 08:17:18 +0000 |
---|---|---|
committer | Olav Morken <olav.morken@uninett.no> | 2011-10-28 08:17:18 +0000 |
commit | 1a263f389b8c07742397e87749f4ceccaeafbe62 (patch) | |
tree | 0c9f2b8675c74447b03ebd88dcae5a6c1ce60712 /lib | |
parent | cf2658cd47deb154d3250d23e485f7b9ee93488d (diff) | |
download | simplesamlphp-1a263f389b8c07742397e87749f4ceccaeafbe62.zip simplesamlphp-1a263f389b8c07742397e87749f4ceccaeafbe62.tar.gz simplesamlphp-1a263f389b8c07742397e87749f4ceccaeafbe62.tar.bz2 |
Add support for hashed passwords & add authcrypt:Hash authsource.
Thanks to Dyonisius Visser for implementing this.
git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@2962 44740490-163a-0410-bde0-09ae8108e29a
Diffstat (limited to 'lib')
-rw-r--r-- | lib/SimpleSAML/Utils/Crypto.php | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/lib/SimpleSAML/Utils/Crypto.php b/lib/SimpleSAML/Utils/Crypto.php new file mode 100644 index 0000000..da017b9 --- /dev/null +++ b/lib/SimpleSAML/Utils/Crypto.php @@ -0,0 +1,83 @@ +<? +/** + * A class for crypto related functions + * + * @author Dyonisius Visser, TERENA. <visser@terena.org> + * @package simpleSAMLphp + * @version $Id$ + */ +class SimpleSAML_Utils_Crypto { + + /** + * This function generates a password hash + * @param $password The unencrypted password + * @param $algo The hashing algorithm, capitals, optionally prepended with 'S' (salted) + * @param $salt Optional salt + */ + public static function pwHash($password, $algo, $salt = NULL) { + assert('is_string($algo)'); + assert('is_string($password)'); + + if(in_array(strtolower($algo), hash_algos())) { + $php_algo = strtolower($algo); // 'sha256' etc + // LDAP compatibility + return '{' . preg_replace('/^SHA1$/', 'SHA', $algo) . '}' + .base64_encode(hash($php_algo, $password, TRUE)); + } + + // Salt + if(!$salt) { + // Default 8 byte salt, but 4 byte for LDAP SHA1 hashes + $bytes = ($algo == 'SSHA1') ? 4 : 8; + $salt = SimpleSAML_Utilities::generateRandomBytes($bytes, TRUE); + } + + if($algo[0] == 'S' && in_array(substr(strtolower($algo),1), hash_algos())) { + $php_algo = substr(strtolower($algo),1); // 'sha256' etc + // Salted hash, with LDAP compatibility + return '{' . preg_replace('/^SSHA1$/', 'SSHA', $algo) . '}' . + base64_encode(hash($php_algo, $password.$salt, TRUE) . $salt); + } + + throw new Exception('Hashing algoritm \'' . strtolower($algo) . '\' not supported'); + + } + + + /** + * This function checks if a password is valid + * @param $crypted Password as appears in password file, optionally prepended with algorithm + * @param $clear Password to check + */ + public static function pwValid($crypted, $clear) { + assert('is_string($crypted)'); + assert('is_string($clear)'); + + // Match algorithm string ('{SSHA256}', '{MD5}') + if(preg_match('/^{(.*?)}(.*)$/', $crypted, $matches)) { + + // LDAP compatibility + $algo = preg_replace('/^(S?SHA)$/', '${1}1', $matches[1]); + + $cryptedpw = $matches[2]; + + if(in_array(strtolower($algo), hash_algos())) { + // Unsalted hash + return ( $crypted == self::pwHash($clear, $algo) ); + } + + if($algo[0] == 'S' && in_array(substr(strtolower($algo),1), hash_algos())) { + $php_algo = substr(strtolower($algo),1); + // Salted hash + $hash_length = strlen(hash($php_algo, 'whatever', TRUE)); + $salt = substr(base64_decode($cryptedpw), $hash_length); + return ( $crypted == self::pwHash($clear, $algo, $salt) ); + } + + throw new Exception('Hashing algoritm \'' . strtolower($algo) . '\' not supported'); + + } else { + return $crypted === $clear; + } + } +} |