xe-core
xe-core copied to clipboard
md5로 저장된 낡은 md5 해시된 비번을 pbkdf2(md5_hash)로 저장하기
커뮤니티의 낡은 md5
비번은 안전하지 않으며 방통위의 지적사항에 해당됩니다.
모듈을 조금 고쳐서 낡은 md5
해시를 pbkdf2(old_md5_hash)
로 고치게끔 해보았습니다.
마땅히 올릴 곳이 없어 이곳에 올리니 필요하신 분 참고해서 고쳐서 쓰시기 바랍니다.
fix_md5.php
// xe-core 최상위 디렉토리에 복사하여 $ php fix_md5.php
실행함.
<?php
/**
* MD5 Fixer by [email protected]
*
* @license: MIT
* @description: fix old MD5 passwords
*/
define('__XE__', TRUE);
require dirname(__FILE__) . '/config/config.inc.php';
$oContext = Context::getInstance();
$oContext->init();
$oDB = &DB::getInstance();
$query = $oDB->_query("select * from xe_member_expired where password not like 'sha256%'");
//$query = $oDB->_query("select * from xe_member where password not like 'sha256%'");
//$query = $oDB->_query("select * from xe_member_expired where password not like 'sha256%' limit 2");
$result = $oDB->_fetch($query);
$o = new Password();
$algo = 'pbkdf2';
if (!is_array($result)) {
$tmp = $result;
$result = array();
$result[] = $tmp;
}
foreach ($result as $u) {
$oldhash = $u->password;
$newhash = $o->createHash($oldhash, $algo);
echo $u->user_id,"\t",$u->member_srl,"\t",$oldhash,"\t",$newhash,"\t", $u->denied,"\n";
//continue;
$member_srl = $u->member_srl;
// Execute insert or update depending on the value of member_srl
$args = new stdClass;
$args->member_srl = $member_srl;
$args->password = $newhash;
$args->denied = $u->denied;
$output = executeQuery('member_expire.updateMemberPassword', $args);
//$output = executeQuery('member.updateMemberPassword', $args);
if(!$output->toBool()) {
echo $output->getMessage();
echo "Fail to update password for member=",$u->member_srl,"/",$u->user_id,"\n";
exit(-1);
}
}
echo "Total ", sizeof($result), " users password info updated\n";
/* EOF */
member_expire
모듈에 남아있는 낡은 md5 해시를 업데이트 하려면 다음과 같은 query xml을 복사해 넣어줍니다. modules/member_expire/queries/updateMemberPassword.xml
<query id="updateMemberPassword" action="update">
<tables>
<table name="member_expired" />
</tables>
<columns>
<column name="password" var="password" notnull="notnull" />
<column name="denied" var="denied" />
</columns>
<conditions>
<condition operation="equal" column="member_srl" var="member_srl" notnull="notnull" filter="number" />
</conditions>
</query>
마지막으로, 이를 지원하기 위해 고쳐야 할 Password.php 모듈 파일
diff --git a/classes/security/Password.class.php b/classes/security/Password.class.php
index 6ab5947..b354acb 100644
--- a/classes/security/Password.class.php
+++ b/classes/security/Password.class.php
@@ -155,7 +155,20 @@ class Password
$hash = explode(':', $hash);
$hash[3] = base64_decode($hash[3]);
$hash_to_compare = $this->pbkdf2($password, $hash[2], $hash[0], intval($hash[1], 10), strlen($hash[3]));
- return $this->strcmpConstantTime($hash_to_compare, $hash[3]);
+ $check1 = $this->strcmpConstantTime($hash_to_compare, $hash[3]);
+ if ($check1) return $check1;
+
+ // saved hash is pbkdf2(md5(password));
+ $tmp = md5($password);
+ $hash_to_compare = $this->pbkdf2($tmp, $hash[2], $hash[0], intval($hash[1], 10), strlen($hash[3]));
+ $check2 = $this->strcmpConstantTime($hash_to_compare, $hash[3]);
+ if ($check2) return $check2;
+
+ // saved hash is pbkdf2(md5(sha1(md5(password))));
+ $tmp = md5(sha1(md5($password)));
+ $hash_to_compare = $this->pbkdf2($tmp, $hash[2], $hash[0], intval($hash[1], 10), strlen($hash[3]));
+ $check3 = $this->strcmpConstantTime($hash_to_compare, $hash[3]);
+ return $check3;
case 'bcrypt':
$hash_to_compare = $this->bcrypt($password, $hash);
- 꽤 오래전 낡은 코드에는 비번을
md5(sha1(md5(password)))
로 저장하게끔 했던 흔적이 있습니다. 이 방식은 관리자가 의도적으로useSha1
을 켰을때만 사용되고 있었으나, 혹시 몰라 추가해 두었습니다.