Code :
<?php
function crypte($phrase,$e,$n)
{
$phrase = base64_encode($phrase);
$taille = strlen($phrase);
$arr = array();
for($i = 0; $i<$taille; $i++)
{
// (Hexa ^ e ) % n
// echo gmp_strval(gmp_pow(ord($phrase[$i]), $e));
$arr[] = gmp_intval(gmp_mod(gmp_pow(ord($phrase[$i]), $e), $n));
}
return $arr;
}
function decrypte($arr,$d,$n)
{
$taille = count($arr);
$phrase = "";
for($i = 0; $i<$taille; $i++)
{
// (Crypté ^ d ) % n
$phrase .= chr(gmp_mod(gmp_pow($arr[$i], $d), $n));
}
$phrase = base64_decode($phrase);
return $phrase;
}
function getPremier()
{
$rand = "";
//taille de la chaine = 6
$size = 4;
$largeNumberMax = str_repeat("9",$size);
$largeNumberMin = "1".str_repeat("0",($size-1));
while(true)
{
$rand = gmp_random();
$cmp = gmp_cmp($rand, gmp_init($largeNumberMin));
if($cmp <= 0)
{
continue;
}
$chaine = substr(gmp_strval($rand),0,$size);
$rand = gmp_init($chaine);
while(gmp_prob_prime($rand) <= 1)
{
//echo gmp_prob_prime($rand)."<br/>";
//echo "pas premier : ".gmp_strval($rand)."<br/>";
$rand = gmp_add($rand , 1);
}
break;
}
return $rand;
}
function getCle()
{
//p et q deux nombres premiers
$p = getPremier();
$q = getPremier();
echo "p = ".gmp_strval($p)."<br/>";
echo "q = ".gmp_strval($q)."<br/>";
$n= gmp_mul($p,$q); //=1073
$Phi2n = gmp_mul(gmp_sub($q,1),gmp_sub($p,1)); //= 1008 : formule d'Euler
//Nous devons déterminer e tel qu'il soit premier avec f(n),
//plus grand que p et q, et plus petit que f(n)->e = 73
$max = (gmp_cmp($p,$q) == 1 ? $p : $q);
$e = null;
while ($e == null)
{
$d = gmp_add($max,1);
if(gmp_intval(gmp_gcd($max, $Phi2n)) == 1)
{
$e = $max;
break;
}
}
echo "e = ".gmp_strval($e)."<br/>";
//Déterminer d tel que e * d mod Phi2n = 1 ->d = 649
$d = gmp_init(2);
while(true)
{
if(gmp_intval(gmp_mod(gmp_mul($e,$d),$Phi2n)) == 1)
break;
$d = gmp_add($d,1);
}
echo "d = ".gmp_strval($d)."<br/><br/>";
echo "cles publiques (e,n): ".gmp_strval($e).",".gmp_strval($n)."<br/>";
echo "cles privées (d,n): ".gmp_strval($d).",".gmp_strval($n)."<br/><br/>";
return array('public' => array($e,$n),'privee' => array($d,$n));
}
/**********************************/
/* TESTS */
/**********************************/
//test1();
test2();
function test1()
{
$clefs = getCle();
$clefsPublique = $clefs['public'];
$clefsPrivee = $clefs['privee'];
}
function test2()
{
//cles publiques (e,n): 409,129653
//cles privées (d,n): 121993,129653
$e = 409;
$n = 129653;
$d = 121993;
//cles publiques (e,n): 3389,9553591
//cles privées (d,n): 1805805,9553591
$e = 3389;
$n = 9553591;
$d = 1805805;
$chaine = 'Hello world!';
echo "<br/>chaine : ".$chaine;
$crypt = crypte($chaine,$e,$n);
echo "<br/>chaine cryptee : ".serialize($crypt);
$decrypt = decrypte($crypt,$d,$n);
echo "<br/>chaine decryptee : ".$decrypt;
}
?>
A noté que du coup je suis passé en attendant à un autre type de cryptage, moins sécurisé mais plus rapide et hybride de surcroit.