PvPGN:SRP — различия между версиями

Материал из WikiServia
Перейти к: навигация, поиск
м
 
Строка 1: Строка 1:
 
Хеш хранится в BNET\acct\salt (соль) и BNET\acct\verifier в виде шестнадцатеричных строк.
 
Хеш хранится в BNET\acct\salt (соль) и BNET\acct\verifier в виде шестнадцатеричных строк.
 +
 +
Алгоритм генерации:
 +
 +
g = 0x2F
 +
N = 0xF8FF1A8B619918032186B68CA092B5557E976C78C73212D91216F6658523C787
 +
 +
x = reverse_bytes( sha1(salt, sha1(upper(username),":", upper(password))) )
 +
verifier = reverse_bytes(g^x % N)
 +
 +
сохраняем salt и verifier, хэш пароля (x) уничтожаем
  
 
Готовые реализации на разных языках можно скачать по ссылке http://harpywar.pvpgn.pl/?do=srp
 
Готовые реализации на разных языках можно скачать по ссылке http://harpywar.pvpgn.pl/?do=srp
Строка 5: Строка 15:
 
== Python ==
 
== Python ==
  
Утилита на Python для генерации SRP хешей (by xpeh)
+
Утилита на Python для генерации SRP хешей by xpeh
  
 
[http://forums.harpywar.com/viewtopic.php?id=564]
 
[http://forums.harpywar.com/viewtopic.php?id=564]

Текущая версия на 01:54, 12 декабря 2012

Хеш хранится в BNET\acct\salt (соль) и BNET\acct\verifier в виде шестнадцатеричных строк.

Алгоритм генерации:

g = 0x2F
N = 0xF8FF1A8B619918032186B68CA092B5557E976C78C73212D91216F6658523C787

x = reverse_bytes( sha1(salt, sha1(upper(username),":", upper(password))) )
verifier = reverse_bytes(g^x % N)

сохраняем salt и verifier, хэш пароля (x) уничтожаем

Готовые реализации на разных языках можно скачать по ссылке http://harpywar.pvpgn.pl/?do=srp

Python

Утилита на Python для генерации SRP хешей by xpeh

[1]

PHP

<?php
// calculates Warcraft 3 Battle.Net & pvpgn 1.99.x SRP hash (verifier)
// authors: basman, harpywar
// date: sep 2012
// (it's needed to enable php_gmp extension http://www.php.net/manual/en/book.gmp.php)
// 
final class BnetSRP3
{
	const g = '2F';
	const N = 'F8FF1A8B619918032186B68CA092B5557E976C78C73212D91216F6658523C787';
	
	public static function getVerifier($username, $password, $salt = null)
	{
		$salt_bytes = self::hex2bin($salt); 
		
		$gmp_g = gmp_init(self::g, 16);
		$gmp_N = gmp_init(self::N, 16);

		$x = self::hexrev(sha1( $salt_bytes . self::hex2bin(sha1( strtoupper($username) . ':' . strtoupper($password) )) ));
		
		$gmp_x = gmp_init($x, 16);
		$gmp_v = gmp_powm($gmp_g, $gmp_x, $gmp_N);
		
		$verifier = self::hexrev( gmp_strval($gmp_v, 16) );
		return strtoupper($verifier);
	}
	
	// convert hex to binary
	private static function hex2bin($str)
	{
		return pack('H*', $str);
	}

	// reverse hex string
	private static function hexrev($str)
	{
		if ( strlen($str) % 2 !== 0 )
			$str = "0" . $str;

		$new_str = "";
		for ($i = 0; $i < strlen($str); $i += 2)
			$new_str .= strrev( substr($str, $i, 2) );

		return strrev($new_str);
	}
	
	// random 256-bit hex string
	public static function rndsalt()
	{
		$random_salt = "";
		if(function_exists('openssl_random_pseudo_bytes'))
		{
			$strong = false;
			$random_salt = openssl_random_pseudo_bytes(32, $strong);
			if($random_salt !== FALSE && $strong)
			{
				return strtoupper( bin2hex($random_salt) );
			}
		}
		
		$random_salt = hash('sha256', mt_rand(0,100) . mt_rand(0,100) . mt_rand(0,100) . mt_rand(0,100));
		return strtoupper($random_salt);
	}
}

Usage example:

$username = 'username';
$password = 'password';
$salt = BnetSRP3::rndsalt(); // random salt

echo BnetSRP3::getVerifier($username, $password, $salt);

Тестовые данные

username: username 
password: password 
salt: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF

password hash: a145033a2417b6e9de9d649a5aa5058ec6ddecf6
verifier : f8e63df16088154a8a2fa63b96d33454b0c61c22e156eb655caf7f5947208b4b