-
Notifications
You must be signed in to change notification settings - Fork 157
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
use libsodium for encryption if it's available
- Loading branch information
1 parent
5926ab9
commit a536cca
Showing
4 changed files
with
120 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
<?php | ||
|
||
/** | ||
* Encryption with the libsodium extension | ||
* | ||
* This extends our standard encryption and will override it if libsodium is | ||
* present. Checking a password and converting cipher text to clear text fall | ||
* back to the standard Hm_Crypt library if they fail. This is to ensure | ||
* backwards compatibility. | ||
* | ||
* @package framework | ||
* @subpackage crypt | ||
*/ | ||
|
||
class Hm_Crypt extends Hm_Crypt_Base { | ||
|
||
/** | ||
* Convert ciphertext to plaintext | ||
* @param string $string ciphertext to decrypt | ||
* @param string $key encryption key | ||
* @return string decrypted text | ||
*/ | ||
public static function plaintext($string, $key) { | ||
if (!LIBSODIUM) { | ||
return parent::plaintext($string, $key); | ||
} | ||
$res = false; | ||
$raw_string = base64_decode($string); | ||
if (!$raw_string || strlen($raw_string) < 60) { | ||
return false; | ||
} | ||
list($salt, $crypt_key) = self::keygen($key, substr($raw_string, 0, 24)); | ||
$hmac = substr($raw_string, 24, 32); | ||
$crypt_string = substr($raw_string, 56); | ||
|
||
if (\Sodium\crypto_auth_verify($hmac, $crypt_string, $crypt_key)) { | ||
$res = Sodium\crypto_secretbox_open($crypt_string, $salt, $crypt_key); | ||
} | ||
if ($res === false) { | ||
return parent::plaintext($string, $key); | ||
} | ||
return $res; | ||
} | ||
|
||
/** | ||
* Convert plaintext into ciphertext | ||
* @param string $string plaintext to encrypt | ||
* @param string $key encryption key | ||
* @return string encrypted text | ||
*/ | ||
public static function ciphertext($string, $key) { | ||
if (!LIBSODIUM) { | ||
return parent::ciphertext($string, $key); | ||
} | ||
list($salt, $key) = self::keygen($key); | ||
$ciphertext = \Sodium\crypto_secretbox($string, $salt, $key); | ||
$mac = \Sodium\crypto_auth($ciphertext, $key); | ||
return base64_encode($salt.$mac.$ciphertext); | ||
} | ||
|
||
/** | ||
* Hash a password using libsodium. Args not defined here are for backwards | ||
* compat usage with our built in crypto | ||
* @param string $password password to hash | ||
* @return string | ||
*/ | ||
public static function hash_password($password, $salt=false, $count=false, $algo='sha512', $type='php') { | ||
if (!LIBSODIUM) { | ||
return parent::hash_password($password, $salt, $count, $algo, $type); | ||
} | ||
return Sodium\crypto_pwhash_str( $password, | ||
\Sodium\CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, | ||
\Sodium\CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE | ||
); | ||
} | ||
|
||
/** | ||
* Check a password against it's stored hash using libsodium. If that | ||
* fails, try our built in crypto otherwise updating to libsodium breaks | ||
* everything | ||
* @param string $password clear text password | ||
* @param string $hash hashed password | ||
* @return bool | ||
*/ | ||
public static function check_password($password, $hash) { | ||
if (!LIBSODIUM) { | ||
return parent::check_password($password, $hash); | ||
} | ||
if (!\Sodium\crypto_pwhash_str_verify($hash, $password)) { | ||
return parent::check_password($password, $hash); | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* stretch (or shrink) a key for libsodium | ||
* @param string $key the key to stretch/shrink | ||
* @param string $salt a salt to use, or create one if needed | ||
* @return array | ||
*/ | ||
private static function keygen($key, $salt=false) { | ||
if (!$salt) { | ||
$salt = \Sodium\randombytes_buf(\Sodium\CRYPTO_SECRETBOX_NONCEBYTES); | ||
} | ||
return array($salt, parent::pbkdf2($key, $salt, 32, parent::$encryption_rounds, parent::$hmac)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters