Merge pull request #181 from Sopsy/master

Add support for difficulty setting for php_crypt
pull/194/head
David Goodwin 7 years ago committed by GitHub
commit a787c0fc1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -174,6 +174,12 @@ $CONF['smtp_client'] = '';
// mysql_encrypt = useful for PAM integration // mysql_encrypt = useful for PAM integration
// authlib = support for courier-authlib style passwords - also set $CONF['authlib_default_flavor'] // authlib = support for courier-authlib style passwords - also set $CONF['authlib_default_flavor']
// dovecot:CRYPT-METHOD = use dovecotpw -s 'CRYPT-METHOD'. Example: dovecot:CRAM-MD5 // dovecot:CRYPT-METHOD = use dovecotpw -s 'CRYPT-METHOD'. Example: dovecot:CRAM-MD5
// php_crypt:CRYPT-METHOD:DIFFICULTY = use PHP built in crypt()-function. Example: php_crypt:SHA512:50000
// - php_crypt CRYPT-METHOD: Supported values are DES, MD5, BLOWFISH, SHA256, SHA512
// - php_crypt DIFFICULTY: Larger value is more secure, but uses more CPU and time for each login.
// - php_crypt DIFFICULTY: Set this according to your CPU processing power.
// - php_crypt DIFFICULTY: Supported values are BLOWFISH:4-31, SHA256:1000-999999999, SHA512:1000-999999999
// - php_crypt DIFFICULTY: leave empty to use default values (BLOWFISH:10, SHA256:5000, SHA512:5000). Example: php_crypt:SHA512
// IMPORTANT: // IMPORTANT:
// - don't use dovecot:* methods that include the username in the hash - you won't be able to login to PostfixAdmin in this case // - don't use dovecot:* methods that include the username in the hash - you won't be able to login to PostfixAdmin in this case
// - you'll need at least dovecot 2.1 for salted passwords ('doveadm pw' 2.0.x doesn't support the '-t' option) // - you'll need at least dovecot 2.1 for salted passwords ('doveadm pw' 2.0.x doesn't support the '-t' option)

@ -1067,14 +1067,18 @@ function _pacrypt_php_crypt($pw, $pw_db) {
$salt = $pw_db; $salt = $pw_db;
} else { } else {
$salt_method = 'SHA512'; // hopefully a reasonable default (better than MD5) $salt_method = 'SHA512'; // hopefully a reasonable default (better than MD5)
$hash_difficulty = '';
// no pw provided. create new password hash // no pw provided. create new password hash
if (strpos($CONF['encrypt'], ':') !== false) { if (strpos($CONF['encrypt'], ':') !== false) {
// use specified hash method // use specified hash method
$split_method = explode(':', $CONF['encrypt']); $split_method = explode(':', $CONF['encrypt']);
$salt_method = $split_method[1]; $salt_method = $split_method[1];
if (count($split_method) >= 3) {
$hash_difficulty = $split_method[2];
}
} }
// create appropriate salt for selected hash method // create appropriate salt for selected hash method
$salt = _php_crypt_generate_crypt_salt($salt_method); $salt = _php_crypt_generate_crypt_salt($salt_method, $hash_difficulty);
} }
// send it to PHPs crypt() // send it to PHPs crypt()
$password = crypt($pw, $salt); $password = crypt($pw, $salt);
@ -1085,7 +1089,7 @@ function _pacrypt_php_crypt($pw, $pw_db) {
* @param string $hash_type must be one of: MD5, DES, BLOWFISH, SHA256 or SHA512 (default) * @param string $hash_type must be one of: MD5, DES, BLOWFISH, SHA256 or SHA512 (default)
* @return string * @return string
*/ */
function _php_crypt_generate_crypt_salt($hash_type='SHA512') { function _php_crypt_generate_crypt_salt($hash_type='SHA512', $hash_difficulty=null) {
// generate a salt (with magic matching chosen hash algorithm) for the PHP crypt() function // generate a salt (with magic matching chosen hash algorithm) for the PHP crypt() function
// most commonly used alphabet // most commonly used alphabet
@ -1106,7 +1110,14 @@ function _php_crypt_generate_crypt_salt($hash_type='SHA512') {
case 'BLOWFISH': case 'BLOWFISH':
$length = 22; $length = 22;
$cost = 10; if (empty($hash_difficulty)) {
$cost = 10;
} else {
$cost = (int)$hash_difficulty;
if ($cost < 4 || $cost > 31) {
die('invalid encrypt difficulty setting "' . $hash_difficulty . '" for ' . $hash_type . ', the valid range is 4-31');
}
}
if (version_compare(PHP_VERSION, '5.3.7') >= 0) { if (version_compare(PHP_VERSION, '5.3.7') >= 0) {
$algorithm = '2y'; // bcrypt, with fixed unicode problem $algorithm = '2y'; // bcrypt, with fixed unicode problem
} else { } else {
@ -1118,14 +1129,36 @@ function _php_crypt_generate_crypt_salt($hash_type='SHA512') {
case 'SHA256': case 'SHA256':
$length = 16; $length = 16;
$algorithm = '5'; $algorithm = '5';
if (empty($hash_difficulty)) {
$rounds = '';
} else {
$rounds = (int)$hash_difficulty;
if ($rounds < 1000 || $rounds > 999999999) {
die('invalid encrypt difficulty setting "' . $hash_difficulty . '" for ' . $hash_type . ', the valid range is 1000-999999999');
}
}
$salt = _php_crypt_random_string($alphabet, $length); $salt = _php_crypt_random_string($alphabet, $length);
return sprintf('$%s$%s', $algorithm, $salt); if (!empty($rounds)) {
$rounds = sprintf('rounds=%d$', $rounds);
}
return sprintf('$%s$%s%s', $algorithm, $rounds, $salt);
case 'SHA512': case 'SHA512':
$length = 16; $length = 16;
$algorithm = '6'; $algorithm = '6';
if (empty($hash_difficulty)) {
$rounds = '';
} else {
$rounds = (int)$hash_difficulty;
if ($rounds < 1000 || $rounds > 999999999) {
die('invalid encrypt difficulty setting "' . $hash_difficulty . '" for ' . $hash_type . ', the valid range is 1000-999999999');
}
}
$salt = _php_crypt_random_string($alphabet, $length); $salt = _php_crypt_random_string($alphabet, $length);
return sprintf('$%s$%s', $algorithm, $salt); if (!empty($rounds)) {
$rounds = sprintf('rounds=%d$', $rounds);
}
return sprintf('$%s$%s%s', $algorithm, $rounds, $salt);
default: default:
die("unknown hash type: '$hash_type'"); die("unknown hash type: '$hash_type'");

Loading…
Cancel
Save