Stärkere Passwortverschlüsselung ; update #223
This commit is contained in:
@@ -341,6 +341,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dbv_118() // resize field password to fit to the new hashed passwords
|
||||||
|
{
|
||||||
|
sql("ALTER TABLE `user` MODIFY COLUMN `password` VARCHAR(128)");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// When adding new mutations, take care that they behave well if run multiple
|
// When adding new mutations, take care that they behave well if run multiple
|
||||||
// times. This improves robustness of database versioning.
|
// times. This improves robustness of database versioning.
|
||||||
|
|||||||
@@ -395,6 +395,11 @@
|
|||||||
*/
|
*/
|
||||||
$opt['logic']['password_hash'] = false;
|
$opt['logic']['password_hash'] = false;
|
||||||
|
|
||||||
|
/* password salt
|
||||||
|
* is a random generated String that is appended to the password
|
||||||
|
*/
|
||||||
|
$opt['logic']['password_salt'] = '';
|
||||||
|
|
||||||
/* new lows style
|
/* new lows style
|
||||||
*/
|
*/
|
||||||
$opt['logic']['new_logs_per_country'] = true;
|
$opt['logic']['new_logs_per_country'] = true;
|
||||||
|
|||||||
34
htdocs/lib2/logic/crypt.class.php
Normal file
34
htdocs/lib2/logic/crypt.class.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
/***************************************************************************
|
||||||
|
* For license information see doc/license.txt
|
||||||
|
*
|
||||||
|
* Cryptographic library for encryption of passwords.
|
||||||
|
*
|
||||||
|
* Unicode Reminder メモ
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
class crypt
|
||||||
|
{
|
||||||
|
static function encryptPassword($password)
|
||||||
|
{
|
||||||
|
// Calls the password encryption chained
|
||||||
|
$pwmd5 = crypt::firstStagePasswordEncryption($password);
|
||||||
|
return crypt::secondStagePasswordEncryption($pwmd5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function firstStagePasswordEncryption($password)
|
||||||
|
{
|
||||||
|
return md5($password);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function secondStagePasswordEncryption($password)
|
||||||
|
{
|
||||||
|
global $opt;
|
||||||
|
if ($opt['logic']['password_hash'])
|
||||||
|
{
|
||||||
|
return hash_hmac('sha512', $password, $opt['logic']['password_salt']);
|
||||||
|
}
|
||||||
|
return $password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -15,6 +15,7 @@ require_once($opt['rootpath'] . 'lib2/logic/countriesList.class.php');
|
|||||||
require_once($opt['rootpath'] . 'lib2/logic/picture.class.php');
|
require_once($opt['rootpath'] . 'lib2/logic/picture.class.php');
|
||||||
require_once($opt['rootpath'] . 'lib2/logic/cache.class.php');
|
require_once($opt['rootpath'] . 'lib2/logic/cache.class.php');
|
||||||
require_once($opt['rootpath'] . 'lib2/logic/cracklib.inc.php');
|
require_once($opt['rootpath'] . 'lib2/logic/cracklib.inc.php');
|
||||||
|
require_once($opt['rootpath'] . 'lib2/logic/crypt.class.php');
|
||||||
require_once($opt['rootpath'] . 'lib2/translate.class.php');
|
require_once($opt['rootpath'] . 'lib2/translate.class.php');
|
||||||
|
|
||||||
class user
|
class user
|
||||||
@@ -155,21 +156,17 @@ class user
|
|||||||
{
|
{
|
||||||
return $this->reUser->getValue('password');
|
return $this->reUser->getValue('password');
|
||||||
}
|
}
|
||||||
function setPassword($value)
|
function setPassword($password)
|
||||||
{
|
{
|
||||||
global $opt;
|
if (!mb_ereg_match(REGEX_PASSWORD, $password))
|
||||||
|
|
||||||
if (!mb_ereg_match(REGEX_PASSWORD, $value))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (cracklib_checkPW($value, array('open', 'caching', 'cache', $this->getUsername(), $this->getFirstName(), $this->getLastName())) == false)
|
if (cracklib_checkPW($password, array('open', 'caching', 'cache', $this->getUsername(), $this->getFirstName(), $this->getLastName())) == false)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
$pwmd5 = md5($value);
|
$encryptedPassword = crypt::encryptPassword($password);
|
||||||
if ($opt['logic']['password_hash'])
|
|
||||||
$pwmd5 = hash('sha512', $pwmd5);
|
|
||||||
|
|
||||||
return $this->reUser->setValue('password', $pwmd5);
|
return $this->reUser->setValue('password', $encryptedPassword);
|
||||||
}
|
}
|
||||||
function getFirstName()
|
function getFirstName()
|
||||||
{
|
{
|
||||||
@@ -197,7 +194,6 @@ class user
|
|||||||
}
|
}
|
||||||
function getCountry()
|
function getCountry()
|
||||||
{
|
{
|
||||||
global $opt;
|
|
||||||
return countriesList::getCountryLocaleName($this->reUser->getValue('country'));
|
return countriesList::getCountryLocaleName($this->reUser->getValue('country'));
|
||||||
}
|
}
|
||||||
function getCountryCode()
|
function getCountryCode()
|
||||||
|
|||||||
@@ -178,16 +178,12 @@ class login
|
|||||||
|
|
||||||
function try_login($user, $password, $permanent)
|
function try_login($user, $password, $permanent)
|
||||||
{
|
{
|
||||||
global $opt;
|
|
||||||
|
|
||||||
if ($password == '')
|
if ($password == '')
|
||||||
return LOGIN_EMPTY_USERPASSWORD;
|
return LOGIN_EMPTY_USERPASSWORD;
|
||||||
|
|
||||||
$pwmd5 = md5($password);
|
$encryptedPassword = crypt::encryptPassword($password);
|
||||||
if ($opt['logic']['password_hash'])
|
|
||||||
$pwmd5 = hash('sha512', $pwmd5);
|
|
||||||
|
|
||||||
return $this->try_login_md5($user, $pwmd5, $permanent);
|
return $this->try_login_encrypted($user, $encryptedPassword, $permanent);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkLoginsCount()
|
function checkLoginsCount()
|
||||||
@@ -207,12 +203,11 @@ class login
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function try_login_md5($user, $pwmd5, $permanent)
|
function try_login_encrypted($user, $encryptedPassword, $permanent)
|
||||||
{
|
{
|
||||||
global $opt;
|
|
||||||
$this->pClear();
|
$this->pClear();
|
||||||
|
|
||||||
if ($user == '' || $pwmd5 == '')
|
if ($user == '' || $encryptedPassword == '')
|
||||||
return LOGIN_EMPTY_USERPASSWORD;
|
return LOGIN_EMPTY_USERPASSWORD;
|
||||||
|
|
||||||
if ($this->checkLoginsCount() == false)
|
if ($this->checkLoginsCount() == false)
|
||||||
@@ -224,7 +219,7 @@ class login
|
|||||||
|
|
||||||
// compare $user with email and username, if both matches use email
|
// compare $user with email and username, if both matches use email
|
||||||
$rsUser = sqlf("SELECT `user_id`, `username`, 2 AS `prio`, `is_active_flag`, `permanent_login_flag`, `admin` FROM `user` WHERE `username`='&1' AND `password`='&2' UNION
|
$rsUser = sqlf("SELECT `user_id`, `username`, 2 AS `prio`, `is_active_flag`, `permanent_login_flag`, `admin` FROM `user` WHERE `username`='&1' AND `password`='&2' UNION
|
||||||
SELECT `user_id`, `username`, 1 AS `prio`, `is_active_flag`, `permanent_login_flag`, `admin` FROM `user` WHERE `email`='&1' AND `password`='&2' ORDER BY `prio` ASC LIMIT 1", $user, $pwmd5);
|
SELECT `user_id`, `username`, 1 AS `prio`, `is_active_flag`, `permanent_login_flag`, `admin` FROM `user` WHERE `email`='&1' AND `password`='&2' ORDER BY `prio` ASC LIMIT 1", $user, $encryptedPassword);
|
||||||
$rUser = sql_fetch_assoc($rsUser);
|
$rUser = sql_fetch_assoc($rsUser);
|
||||||
sql_free_result($rsUser);
|
sql_free_result($rsUser);
|
||||||
|
|
||||||
|
|||||||
48
local/maintenance/update_passwords.php
Normal file
48
local/maintenance/update_passwords.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
/***************************************************************************
|
||||||
|
* For license information see doc/license.txt
|
||||||
|
*
|
||||||
|
* This script converts all md5-passwords to salted hash passwords.
|
||||||
|
*
|
||||||
|
* Unicode Reminder メモ
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
global $opt;
|
||||||
|
$opt['rootpath'] = '../htdocs/';
|
||||||
|
require($opt['rootpath'] . 'lib2/web.inc.php');
|
||||||
|
require($opt['rootpath'] . 'lib2/logic/crypt.class.php');
|
||||||
|
|
||||||
|
if (!isset($opt['logic']['password_salt']) || strlen($opt['logic']['password_salt']) < 32)
|
||||||
|
{
|
||||||
|
echo "Warning!\nPassword Salt not set or too short!\n\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!$opt['logic']['password_hash'])
|
||||||
|
{
|
||||||
|
echo "Warning!\nHashed Passwords not enabled!\n\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rs = sql("SELECT * FROM user where password is not null");
|
||||||
|
while ($r = sql_fetch_array($rs))
|
||||||
|
{
|
||||||
|
$password = $r['password'];
|
||||||
|
if (strlen($password) == 128)
|
||||||
|
{
|
||||||
|
echo "Password seems to be already converted, ommit this password\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strlen($password) < 32)
|
||||||
|
{
|
||||||
|
$password = crypt::firstStagePasswordEncryption($password);
|
||||||
|
}
|
||||||
|
$pwhash = crypt::secondStagePasswordEncryption($password);
|
||||||
|
|
||||||
|
sql("UPDATE `user` SET `password`='&1' WHERE `user_id`='&2'", $pwhash, $r['user_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_free_result($rs);
|
||||||
|
|
||||||
|
echo "Update of passwords finished.\n";
|
||||||
|
|
||||||
|
?>
|
||||||
31
local/test/lib2/logic/PasswordEncryptionTest.php
Normal file
31
local/test/lib2/logic/PasswordEncryptionTest.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
/****************************************************************************
|
||||||
|
|
||||||
|
Unicode Reminder メモ
|
||||||
|
|
||||||
|
Password Encryption Test
|
||||||
|
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
require '../../../../htdocs/lib2/logic/crypt.class.php';
|
||||||
|
|
||||||
|
class PasswordEncryptionTest extends PHPUnit_Framework_TestCase {
|
||||||
|
|
||||||
|
function testPasswordEncryption()
|
||||||
|
{
|
||||||
|
global $opt;
|
||||||
|
$opt['logic']['password_hash'] = false;
|
||||||
|
|
||||||
|
$plain_text = 'very important data';
|
||||||
|
|
||||||
|
$md5HashedPassword = crypt::encryptPassword($plain_text);
|
||||||
|
$this->assertEquals('c75ac45eabed45d667359462b6a8e93e', $md5HashedPassword);
|
||||||
|
|
||||||
|
$opt['logic']['password_hash'] = true;
|
||||||
|
$opt['logic']['password_salt'] = '?S<,XyB1Y[y_Gz>b';
|
||||||
|
|
||||||
|
$encryptedPassword = crypt::encryptPassword($plain_text);
|
||||||
|
$this->assertEquals('8b1d376a76e6430738d8322a6e3f4ebd5e8632f67052de7b74c8ca745bda6f11c7ea05db7de0c14bb097d3033557eb81d7fae21de988efc5353ed2f77dab504b', $encryptedPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user