New file |
0,0 → 1,224 |
<?php |
|
/** |
* Classe utilitaire proposant des fonctions permettant la réalisation d'un |
* échange de clé Diffie Hellman |
* |
* "En cryptographie, l'échange de clés Diffie-Hellman, du nom de ses auteurs |
* Whitfield Diffie et Martin Hellman, est une méthode par laquelle deux |
* personnes peuvent se mettre d'accord sur un nombre (qu'ils peuvent utiliser |
* comme clé pour chiffrer la conversation suivante) sans qu'une troisième |
* personne appelée Ève puisse découvrir le nombre, même en ayant écouté tous |
* leurs échanges." |
* |
* Voir http://fr.wikipedia.org/wiki/%C3%89change_de_cl%C3%A9s_Diffie-Hellman |
* |
* */ |
class DiffieHellmanUtil { |
|
// Default Diffie-Hellman key generator (1024 bit) |
const DH_P = 'dcf93a0b883972ec0e19989ac5a2ce310e1d37717e8d9571bb7623731866e61ef75a2e27898b057f9891c2e27a639c3f29b60814581cd3b2ca3986d2683705577d45c2e7e52dc81c7a171876e5cea74b1448bfdfaf18828efd2519f14e45e3826634af1949e5b535cc829a483b8a76223e5d490a257f05bdff16f2fb22c583ab'; |
|
//Default Diffie-Hellman prime number (should be 2 or 5) |
const DH_G = '02'; |
|
|
|
|
/** |
* Performs the first step of a Diffie-Hellman key exchange by generating |
* private and public DH values based on given prime number $p and |
* generator $g. Both sides of key exchange MUST have the same prime number |
* and generator. In this case they will able to create a random shared |
* secret that is never send from one to the other. |
* |
* @param string $p prime number in binary representation |
* @param string $g generator in binary representation |
* @param string $priv_key private key in binary representation |
* @return mixed |
*/ |
public static function createDhKey($p, $g, $priv_key = null) |
{ |
if (function_exists('openssl_dh_compute_key')) { |
$dh_details = array( |
'p' => $p, |
'g' => $g |
); |
if ($priv_key !== null) { |
$dh_details['priv_key'] = $priv_key; |
} |
return openssl_pkey_new(array('dh'=>$dh_details)); |
} else { |
$bn_p = self::binToBigNum($p); |
$bn_g = self::binToBigNum($g); |
if ($priv_key === null) { |
$priv_key = self::randomBytes(self::strlen($p)); |
} |
$bn_priv_key = self::binToBigNum($priv_key); |
if (extension_loaded('gmp')) { |
$bn_pub_key = gmp_powm($bn_g, $bn_priv_key, $bn_p); |
} else if (extension_loaded('bcmath')) { |
$bn_pub_key = bcpowmod($bn_g, $bn_priv_key, $bn_p); |
} |
$pub_key = self::bigNumToBin($bn_pub_key); |
|
return array( |
'p' => $bn_p, |
'g' => $bn_g, |
'priv_key' => $bn_priv_key, |
'pub_key' => $bn_pub_key, |
'details' => array( |
'p' => $p, |
'g' => $g, |
'priv_key' => $priv_key, |
'pub_key' => $pub_key)); |
} |
} |
|
/** |
* Returns an associative array with Diffie-Hellman key components in |
* binary representation. The array includes original prime number 'p' and |
* generator 'g', random private key 'priv_key' and corresponding public |
* key 'pub_key'. |
* |
* @param mixed $dh Diffie-Hellman key |
* @return array |
*/ |
public static function getDhKeyDetails($dh) |
{ |
if (function_exists('openssl_dh_compute_key')) { |
$details = openssl_pkey_get_details($dh); |
if (isset($details['dh'])) { |
return $details['dh']; |
} |
} else { |
return $dh['details']; |
} |
} |
|
|
|
// Depuis OpenId.php, les fonctions de Diffie-Hellman |
// TODO : voir si ça peut être externaliser pour être réutilisé ? => dans utilitaires |
/** |
* Computes the shared secret from the private DH value $dh and the other |
* party's public value in $pub_key |
* |
* @param string $pub_key other party's public value |
* @param mixed $dh Diffie-Hellman key |
* @return string |
* @throws Zend_OpenId_Exception |
*/ |
public function computeDhSecret($pub_key, $dh) |
{ |
if (function_exists('openssl_dh_compute_key')) { |
$ret = openssl_dh_compute_key($pub_key, $dh); |
if (ord($ret[0]) > 127) { |
$ret = "\0" . $ret; |
} |
return $ret; |
} else if (extension_loaded('gmp')) { |
$bn_pub_key = self::binToBigNum($pub_key); |
$bn_secret = gmp_powm($bn_pub_key, $dh['priv_key'], $dh['p']); |
return self::bigNumToBin($bn_secret); |
} else if (extension_loaded('bcmath')) { |
$bn_pub_key = self::binToBigNum($pub_key); |
$bn_secret = bcpowmod($bn_pub_key, $dh['priv_key'], $dh['p']); |
return self::bigNumToBin($bn_secret); |
} |
/*require_once "Zend/OpenId/Exception.php"; |
throw new Zend_OpenId_Exception( |
'The system doesn\'t have proper big integer extension', |
Zend_OpenId_Exception::UNSUPPORTED_LONG_MATH);*/ |
|
trigger_error('Le système ne gère pas les nombre de taille arbitraire', E_STRICT); |
} |
|
/** |
* Takes an arbitrary precision integer and returns its shortest big-endian |
* two's complement representation. |
* |
* Arbitrary precision integers MUST be encoded as big-endian signed two's |
* complement binary strings. Henceforth, "btwoc" is a function that takes |
* an arbitrary precision integer and returns its shortest big-endian two's |
* complement representation. All integers that are used with |
* Diffie-Hellman Key Exchange are positive. This means that the left-most |
* bit of the two's complement representation MUST be zero. If it is not, |
* implementations MUST add a zero byte at the front of the string. |
* |
* @param string $str binary representation of arbitrary precision integer |
* @return string big-endian signed representation |
*/ |
public function btwoc($str) |
{ |
if (ord($str[0]) > 127) { |
return "\0" . $str; |
} |
return $str; |
} |
|
|
|
/** |
* Produces string of random byte of given length. |
* |
* @param integer $len length of requested string |
* @return string RAW random binary string |
*/ |
public function randomBytes($len) |
{ |
$key = ''; |
for($i=0; $i < $len; $i++) { |
$key .= chr(mt_rand(0, 255)); |
} |
return $key; |
} |
|
/** |
* Returns lenght of binary string in bytes |
* |
* @param string $str |
* @return int the string lenght |
*/ |
static public function strlen($str) |
{ |
if (extension_loaded('mbstring') && |
(((int)ini_get('mbstring.func_overload')) & 2)) { |
return mb_strlen($str, 'latin1'); |
} else { |
return strlen($str); |
} |
} |
|
|
/** |
* Converts binary representation into ext/gmp or ext/bcmath big integer |
* representation. |
* |
* @param string $bin binary representation of big number |
* @return mixed |
* @throws Zend_OpenId_Exception |
*/ |
protected function binToBigNum($bin) |
{ |
if (extension_loaded('gmp')) { |
return gmp_init(bin2hex($bin), 16); |
} else if (extension_loaded('bcmath')) { |
$bn = 0; |
$len = self::strlen($bin); |
for ($i = 0; $i < $len; $i++) { |
$bn = bcmul($bn, 256); |
$bn = bcadd($bn, ord($bin[$i])); |
} |
return $bn; |
} |
/*require_once "Zend/OpenId/Exception.php"; |
throw new Zend_OpenId_Exception( |
'The system doesn\'t have proper big integer extension', |
Zend_OpenId_Exception::UNSUPPORTED_LONG_MATH);*/ |
|
trigger_error('Le système ne gère pas les nombre de taille arbitraire', E_STRICT); |
} |
|
} |
?> |
Property changes: |
Added: svn:keywords |
+Id Author Date Revision HeadURL |
\ No newline at end of property |