Un domaine dans lequel je ne m'étais jamais penché : la cryptographie de donnée. Le principe est simple, transférer des données entre deux personnes en empêchant la lecture par une personne Tiers.

+ d'info sur wikipedia

C'est pour la réalisation d'un module de communication inter-site que je me suis penché pour la première fois sur la création d'un code PHP qui ferrait le travail de cryptage pour moi.

Etant donné l'absence totale de formation sur le sujet (j'aurais pas du sécher les cours de cryptage bordel) je suis partis à la pêche aux informations sur internet et malheureusement les aides ne sont pas présente en grand nombre lorsqu'il s'agit de détailler les algorithmes de génération de clés & co. Tout au plus on apprend que l'on utilisera tel et tel théorème sans entrer dans les détails. Et justement c'est ces détails que je souhaitais avoir...

Bref une bonne journée de recherche + tard je suis tombé sur un site détaillant le pourquoi du comment avec moults exemples (voir le site)

De là j'ai pu enfin coder mon propre programme qui simule le cryptage RSA.

Attention : nécessite l'activation de la librairie GMP dans le php.ini

<?php

/*function PGCD($a, $b)
{
if ($b == 0)
return $a;
else
return PGCD($b, $a % $b);
}*/

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;
}


?>

 

Le souci a l'heure actuelle est la puissance du PC qui limite les possibilités de calcul des clés + cryptage & décryptage à des clés d'une longueur de 5 caractères maxi.... bien loin des 512 recommandés...

je reste donc en recherche d'une solution...