#685 Add php implementation for PBKDF2

- Create php sample for PBKDF2
- Rename pbkdf2 java classes (remove Crypt prefix)
- Remove options from hash setting comment that should not be used
This commit is contained in:
ljacqu 2016-11-25 16:41:55 +01:00
parent de5324bbc6
commit 122c6586bc
9 changed files with 75 additions and 21 deletions

View File

@ -109,7 +109,6 @@ abstract class AuthMeController {
* @return string|null the hash, or null if unavailable (e.g. username doesn't exist)
*/
private function getHashFromDatabase($username) {
// Add here your database host, username, password and database name
$mysqli = $this->getAuthmeMySqli();
if ($mysqli !== null) {
$stmt = $mysqli->prepare('SELECT password FROM ' . self::AUTHME_TABLE . ' WHERE username = ?');

View File

@ -0,0 +1,53 @@
<?php
/***********************************************************
* AuthMe website integration logic for PBKDF2 *
* ------------------------------------------------------- *
* See AuthMeController for details. *
* *
* Source: https://github.com/AuthMe-Team/AuthMeReloaded/ *
***********************************************************/
class Pbkdf2 extends AuthMeController {
/** @var string[] range of characters for salt generation */
private $CHARS;
const SALT_LENGTH = 16;
const NUMBER_OF_ITERATIONS = 10000;
public function __construct() {
$this->CHARS = self::initCharRange();
}
protected function isValidPassword($password, $hash) {
// hash := pbkdf2_sha256$iterations$salt$hash
$parts = explode('$', $hash);
return count($parts) === 4 && $hash === $this->computeHash($parts[1], $parts[2], $password);
}
protected function hash($password) {
$salt = $this->generateSalt();
return $this->computeHash(self::NUMBER_OF_ITERATIONS, $salt, $password);
}
private function computeHash($iterations, $salt, $password) {
return 'pbkdf2_sha256$' . self::NUMBER_OF_ITERATIONS . '$' . $salt
. '$' . hash_pbkdf2('sha256', $password, $salt, self::NUMBER_OF_ITERATIONS, 64, false);
}
/**
* @return string randomly generated salt
*/
private function generateSalt() {
$maxCharIndex = count($this->CHARS) - 1;
$salt = '';
for ($i = 0; $i < self::SALT_LENGTH; ++$i) {
$salt .= $this->CHARS[mt_rand(0, $maxCharIndex)];
}
return $salt;
}
private static function initCharRange() {
return array_merge(range('0', '9'), range('a', 'f'));
}
}

View File

@ -15,7 +15,7 @@ class Sha256 extends AuthMeController {
const SALT_LENGTH = 16;
public function __construct() {
$this->CHARS = self::initRandomChars();
$this->CHARS = self::initCharRange();
}
protected function isValidPassword($password, $hash) {
@ -41,7 +41,7 @@ class Sha256 extends AuthMeController {
return $salt;
}
private static function initRandomChars() {
private static function initCharRange() {
return array_merge(range('0', '9'), range('a', 'f'));
}

View File

@ -1,10 +1,11 @@
package fr.xephi.authme.security;
import fr.xephi.authme.security.crypts.EncryptionMethod;
import fr.xephi.authme.security.crypts.Pbkdf2;
import fr.xephi.authme.security.crypts.Pbkdf2Django;
/**
* The list of hash algorithms supported by AuthMe. The linked {@link EncryptionMethod} implementation
* must be able to be instantiated with the default constructor.
* Hash algorithms supported by AuthMe.
*/
public enum HashAlgorithm {
@ -18,8 +19,8 @@ public enum HashAlgorithm {
MD5(fr.xephi.authme.security.crypts.MD5.class),
MD5VB(fr.xephi.authme.security.crypts.MD5VB.class),
MYBB(fr.xephi.authme.security.crypts.MYBB.class),
PBKDF2(fr.xephi.authme.security.crypts.CryptPBKDF2.class),
PBKDF2DJANGO(fr.xephi.authme.security.crypts.CryptPBKDF2Django.class),
PBKDF2(Pbkdf2.class),
PBKDF2DJANGO(Pbkdf2Django.class),
PHPBB(fr.xephi.authme.security.crypts.PHPBB.class),
PHPFUSION(fr.xephi.authme.security.crypts.PHPFUSION.class),
@Deprecated

View File

@ -7,7 +7,7 @@ import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.Usage;
@Recommendation(Usage.RECOMMENDED)
public class CryptPBKDF2 extends HexSaltedMethod {
public class Pbkdf2 extends HexSaltedMethod {
private static final int NUMBER_OF_ITERATIONS = 10_000;

View File

@ -9,7 +9,7 @@ import fr.xephi.authme.util.StringUtils;
import javax.xml.bind.DatatypeConverter;
@AsciiRestricted
public class CryptPBKDF2Django extends HexSaltedMethod {
public class Pbkdf2Django extends HexSaltedMethod {
private static final int DEFAULT_ITERATIONS = 24000;
@ -32,7 +32,7 @@ public class CryptPBKDF2Django extends HexSaltedMethod {
try {
iterations = Integer.parseInt(line[1]);
} catch (NumberFormatException e) {
ConsoleLogger.warning("Could not read number of rounds for CryptPBKDF2Django:"
ConsoleLogger.warning("Could not read number of rounds for Pbkdf2Django:"
+ StringUtils.formatException(e));
return false;
}

View File

@ -64,9 +64,10 @@ public class SecuritySettings implements SettingsHolder {
newProperty("settings.security.unLoggedinGroup", "unLoggedinGroup");
@Comment({
"Possible values: MD5, SHA1, SHA256, WHIRLPOOL, XAUTH, MD5VB, PHPBB,",
"MYBB, IPB3, PHPFUSION, SMF, XENFORO, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512,",
"DOUBLEMD5, PBKDF2, PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM (for developers only)"
"Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512, WHIRLPOOL,",
"MYBB, IPB3, PHPBB, PHPFUSION, SMF, XENFORO, XAUTH, JOOMLA, WBB3, WBB4, MD5VB,",
"PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM (for developers only). See full list at",
"https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/hash_algorithms.md"
})
public static final Property<HashAlgorithm> PASSWORD_HASH =
newProperty(HashAlgorithm.class, "settings.security.passwordHash", HashAlgorithm.SHA256);

View File

@ -1,12 +1,12 @@
package fr.xephi.authme.security.crypts;
/**
* Test for {@link CryptPBKDF2Django}.
* Test for {@link Pbkdf2Django}.
*/
public class CryptPBKDF2DjangoTest extends AbstractEncryptionMethodTest {
public class Pbkdf2DjangoTest extends AbstractEncryptionMethodTest {
public CryptPBKDF2DjangoTest() {
super(new CryptPBKDF2Django(),
public Pbkdf2DjangoTest() {
super(new Pbkdf2Django(),
"pbkdf2_sha256$15000$50a7ff2d7e00$t7Qx2CfzMhGEbyCa3Wk5nJvNjj3N+FdxhpwJDerl4Fs=", // password
"pbkdf2_sha256$15000$f9d8a58f3fe2$oMqmMGuJetdubW0cpubmT8CltQLjHT+L2GuwKsaWLx8=", // PassWord1
"pbkdf2_sha256$15000$1170bc7a31f5$Ex/2aQsXm4kogLIYARpUPn04ccK5LYYjyVPpl32ALjE=", // &^%te$t?Pw@_

View File

@ -1,12 +1,12 @@
package fr.xephi.authme.security.crypts;
/**
* Test for {@link CryptPBKDF2}.
* Test for {@link Pbkdf2}.
*/
public class CryptPBKDF2Test extends AbstractEncryptionMethodTest {
public class Pbkdf2Test extends AbstractEncryptionMethodTest {
public CryptPBKDF2Test() {
super(new CryptPBKDF2(),
public Pbkdf2Test() {
super(new Pbkdf2(),
"pbkdf2_sha256$10000$b25801311edf$093E38B16DFF13FCE5CD64D5D888EE6E0376A3E572FE5DA6749515EA0F384413223A21C464B0BE899E64084D1FFEFD44F2AC768453C87F41B42CC6954C416900", // password
"pbkdf2_sha256$10000$fe705da06c57$A41527BD58FED9C9E6F452FC1BA8B0C4C4224ECC63E37F71EB1A0865D2AB81BBFEBCA9B7B6A6E8AEF4717B43F8EB6FB4EDEFFBB399D9D991EF7E23013595BAF0", // PassWord1
"pbkdf2_sha256$10000$05603593cdda$1D30D1D90D826C866755969F06C312E21CC3E8DA0B777E2C764700E4E1FD890B731FAF44753D68F3FC025D3EAA709E800FBF2AF61DB23464311FCE7D35353A30", // &^%te$t?Pw@_