J'aimerais vos avis,
Si vous le voulez, vous pouvez utiliser ce script s'il convient à vos besoins.
Si vous voyez une faille quelconque, ou avez des suggestions, n'hésitez pas.
Testé sou IE et Firefox.
Évidement, le Javascript doit être activé.
<?php
// Fichier config.php
// De préférence, ne pas laisser sur le serveur.
// Créé par Stéphane Jacques le 27 février 2009
// Fichier de test d'encryption.
session_start(); // Début de la session
include_once('des.php');
/* inclus la librairie DES de Jim Gibbs téléchargeable
sur http://www.tero.co.uk/des/ */
/*
On définit la clef publique au hasard afin qu'elle ne soit
jamais identique (ou presque).
On attribut aussi un nom et id aléatoires aux champs textes sensibles
afin de brouiller les pistes et ainsi, empêcher la sauvegarde du
mot de passe par le navigateur. Avec un préfixe(ou sufixe), on évite,
le cas échéant, d'avoir 2 valeures identiques pour les noms
et id des champs textes servant au login/mot de passe.
*/
if (!isset($_SESSION['clef_publique']))
{
$_SESSION['clef_publique'] = rand(rand(), time());
$_SESSION['input_login']= "a".rand(rand(), time());
$_SESSION['input_pass']= "w".rand(rand(), time());
}
/*
Cette fonction PHP sert à s'assurer que la clef a bien
24 bits pour le cryptage en DES triple.
*/
function arrange($chaine)
{
while (strlen($chaine) != 24)
{
$a= strlen($chaine) * strlen($chaine);
if (strlen($chaine) >= 25)
{
$chaine = substr($chaine,0,24);
}
elseif (strlen($chaine) <= 23)
{
$chaine .= $a;
}
}
return $chaine;
}
?>
<!-- Début du code HTML -->
<html>
<head>
<!--
On inclut la bibliothèque DES de Paul Tero disponible
sur son site http://www.tero.co.uk/des/
-->
<script type="text/javascript" src="des.js"></script>
<!--
On inclut la bibliothèque MD5 de Paul Johnston disponible
sur son site http://pajhome.org.uk/crypt/md5
Des réglages peuvent être nécessaires. Référez vous au site
internetde l'auteur.
-->
<script type="text/javascript" src="md5.js"></script>
<script type="text/javascript" language="javascript">
/*
Cette fonction Javascript sert à s'assurer que la clef a bien
24 bits pour le cryptage en DES triple.
*/
function arrange(chaine)
{
while (chaine.length != 24)
{
var a= chaine.length * chaine.length;
if (chaine.length >= 25)
{
chaine = chaine.substring(0,24);
}
else if (chaine.length <= 23)
{
chaine += a;
}
}
return chaine;
}
/*
Fonction qui crypte les données du formulaire
avant de les renvoyer sur internet.
*/
function envoit()
{
//on désactive le bouton pour éviter plusieurs cliques des fois que ca soit trop long.
document.getElementById('btn').disabled = 'disabled';
//entrée des valeures pour les tests.
document.getElementById('md5client').value = hex_md5(document.getElementById('clef_publique').value);
document.getElementById('md5clientlabel').innerHTML = hex_md5(document.getElementById('clef_publique').value);
document.getElementById('motdepasse').value = document.getElementById('<?php echo $_SESSION['input_pass']; ?>').value;
document.getElementById('motdepasselabel').innerHTML = document.getElementById('<?php echo $_SESSION['input_pass']; ?>').value;
// On cré la clef de cryptage qui est un hashage de la clef publique ajusté en 24 bits.
var key = arrange(hex_md5(document.getElementById('clef_publique').value));
//On assigne le nom d'utilisateur entré par le client comme étant ce qui doit être crypté.
var message = document.getElementById('<?php echo $_SESSION['input_login']; ?>').value;
// Encryption des données
var encrypte = des (key, message, 1,0);
/*
On change ce que le client a entré comme nom d'utilisateur pour la valeur
hexadécimale du cryptage.
Il est préférable d'utiliser une valeur hexadécimale pour le transfert sur
internet, car sinon, il pourrait manquer des bouts du cryptage une fois rendu
au serveur.
*/
document.getElementById('<?php echo $_SESSION['input_login']; ?>').value = stringToHex(encrypte);
/*
On cré une clef d'encryption qui est la concaténation
de la clef privée (c-à-d le mot de passe de l'utilisateur) et la
clef publique. Toujours ajustée en 24 bits.
*/
var keypass = arrange(document.getElementById('<?php echo $_SESSION['input_pass']; ?>').value + document.getElementById('clef_publique').value);
//On assigne le mot de passe entré par le client comme étant ce qui doit être crypté.
var messagepass = document.getElementById('<?php echo $_SESSION['input_pass']; ?>').value;
//On encrypte les donées.
var encryptepass = des (keypass, messagepass, 1,0);
/*
On change ce que le client a entré comme mot de passe pour la valeur
hexadécimale du cryptage.
Il est préférable d'utiliser une valeur hexadécimale pour le transfert sur
internet, car sinon, il pourrait manquer des bouts du cryptage une fois rendu
au serveur.
*/
document.getElementById('<?php echo $_SESSION['input_pass']; ?>').value = stringToHex(encryptepass);
//On envoit le formulaire au serveur contenant les données cryptées.
//document.getElementById('formulaire').submit();
}
</script>
</head>
<body>
<?php
if ( isset ($_POST[$_SESSION['input_login']]) || isset ($_POST[$_SESSION['input_pass']]) )
{
// on vérifie que le formulaire a bien été envoyé.
if (empty($_POST[$_SESSION['input_login']]) || $_POST[$_SESSION['input_login']] == "0x" )
{
$_SESSION = array(); // vide les champs de la session
session_destroy(); // détruit la session
echo "ERREUR: Nom d'utilisateur manquant!"; // Un beau message!
echo "<meta http-equiv=refresh content=\"2; url=config.php\">"; // on redirige vers la page de login
exit();
}
// on vérifie que le formulaire a bien été envoyé.
if (empty($_POST[$_SESSION['input_pass']]) || $_POST[$_SESSION['input_pass']] == "0x")
{
$_SESSION = array(); // vide les champs de la session
session_destroy(); // détruit la session
echo "ERREUR: Mot de passe manquant!"; // Un beau message!
echo "<meta http-equiv=refresh content=\"2; url=config.php\">"; // on redirige vers la page de login
exit();
}
// Début du décryptage des données envoyée par le client.
// La clef de décryption est un hashage de la clef publique mise en 24 bits.
$clef = arrange(md5($_SESSION['clef_publique']));
//On transforme les données encryptées transmises en mode hexadécimal
//en mode string.
$donnees_encryptees = hexToString($_POST[$_SESSION['input_login']]);
echo "Nom d'utilisateur reçu encrypté : ".$_POST[$_SESSION['input_login']]."<br>";
//On décrypte le nom d'utilisateur.
$utilisateur = trim(des ($clef, $donnees_encryptees, 0, 0, null));
echo "Nom d'utilisateur reçu encrypté et ensuite décrypté par le serveur : ".$utilisateur."<br>";
//On définit la clef privée du serveur. Cette clef est très importante!!!
$clef_privee = trim($_POST['clefprivee']);
//Avec cette clef, on cré une clef de d'enryptage en 24 bits qui est unique à chaque utilisateur.
// Je crois que l'on peut dire qu'elle est signée.
$clef_d_encryption_db = arrange(crypt($clef_privee,$utilisateur));
//c'est la meme chose
$clef_de_decryption_db = arrange(crypt($clef_privee,$utilisateur));
$mot_de_passe_recu_en_clair = $_POST['motdepasse'];
echo "Mot de passe reçu en clair : ".$mot_de_passe_recu_en_clair."<br>";
//on encrypte le mot de passe reçu en clair comme pour le mettre dans la base de données
$mot_de_passe_db = stringToHex(des ($clef_d_encryption_db, $mot_de_passe_recu_en_clair, 1, 0, null));
echo "<br><b>Mot de passe encodé pour base de données
(faire un copier-coller pour le premier utilisateur)</b>
<br> ".$mot_de_passe_db."<br><br>";
//On décrypte le mot de passe venant de la base de données
$mot_de_passe_encrypte_db = hexToString($mot_de_passe_db);
$mot_de_passe = des ($clef_de_decryption_db, $mot_de_passe_encrypte_db, 0, 0, null);
echo "Mot de passe de la base de donné décrypté : ".$mot_de_passe."<br>";
//On remet le mot de passe recu du client en string.
$mot_de_passe_recu_encrypte = hexToString($_POST[$_SESSION['input_pass']]);
echo "Mot de passe reçu encrypté : ".$_POST[$_SESSION['input_pass']]."<br>";
//On cré la clef de décryptage à l'aide du mot de passe décryptée de la base de données.
$clef_de_decryption = arrange(trim($mot_de_passe).$_SESSION['clef_publique']);
//On décrypte le mot de passe envoyé par le client.
$mot_de_passe_recu_decrypte = des ($clef_de_decryption, $mot_de_passe_recu_encrypte, 0, 0, null);
echo "Mot de passe reçu encrypté, décrypté par le serveur : ".$mot_de_passe_recu_decrypte."<br>";
//On comparre les mots de passes
if (trim($mot_de_passe) == trim($mot_de_passe_recu_decrypte))
{
echo "<br><h2>Résultat : OK!</h2><br>";
}
else
{
echo "<br><h2>Résultat : Il y a eu une erreur!</h2><br>";
}
echo "<br>
Hashage MD5 de la clef publique reçu : ".$_POST['md5client']."<br>
<br>
Hashage MD5 de la clef publique par le serveur : ".md5($_SESSION['clef_publique'])."<br>
<br>
<br>
<a href=\"config.php\"> Réessayer</a>
";
$_SESSION = array(); // vide les champs de la session
session_destroy(); // détruit la session
}
else
{
?>
<form id="formulaire" name="formulaire" action="config.php" method="POST">
<p>
Page de test et d'encryption pour le mot de passe de l'administrateur du site.<br>
Permet aussi de comparer les résultats du hashage MD5 entre le client et le serveur.
</p>
Clef publique créée par le serveur : <input type="text" name="clef_publique" id="clef_publique" size="20" disabled value="<?php echo $_SESSION['clef_publique']; ?>"><br>
<br>
Nom d'utilisateur : <input type="text" size="20" id="<?php echo $_SESSION['input_login']; ?>" name="<?php echo $_SESSION['input_login']; ?>"><br>
Mot de passe : <input type="text" size="20" id="<?php echo $_SESSION['input_pass']; ?>" name="<?php echo $_SESSION['input_pass']; ?>"><br>
Clef privee que vous désirez utiliser : <input type="text" name="clefprivee" id="clefprivee" size="100"><br>
<br>
Mot de passe en clair (pour le décryptage. Ce champ est normalement inexistant.) : <label id="motdepasselabel"></label>
<input type="hidden" id="motdepasse" name="motdepasse">
<br>
Résultat du hashage MD5 de la clef publique : <label id="md5clientlabel"></label>
<input type="hidden" name="md5client" id="md5client"><br>
<br>
<br>
<input type="button" name="btn" id="btn" value="Étape 1 - Crypter les données" onclick="envoit();"><br>
<br>
<input type="submit" name="envoyer" id="envoyer" value="Étape 2 - Envoyer le formulaire">
<?php
}
?>
</body>
</html>
Voici un exemple de connexion utilisant cet encryption:
<!--
Fichier login.php
Créé par Stéphane Jacques le 26 février 2009
Fichier de connexion type.
-->
<!-- Début des scripts servants a l'encryption -->
<?php
session_start(); // Début de la session
include_once('des.php');
if (!isset($_SESSION['clef_publique']))
{
$_SESSION['clef_publique'] = rand(rand(), time());
$_SESSION['input_login']= "a".rand(rand(), time());
$_SESSION['input_pass']= "w".rand(rand(), time());
}
function arrange($chaine)
{
while (strlen($chaine) != 24)
{
$a= strlen($chaine) * strlen($chaine);
if (strlen($chaine) >= 25)
{
$chaine = substr($chaine,0,24);
}
elseif (strlen($chaine) <= 23)
{
$chaine .= $a;
}
}
return $chaine;
}
?>
<!-- Début du code HTML -->
<html>
<head>
<script type="text/javascript" src="des.js"></script>
<script type="text/javascript" src="md5.js"></script>
<script type="text/javascript" language="javascript">
function arrange(chaine)
{
while (chaine.length != 24)
{
var a= chaine.length * chaine.length;
if (chaine.length >= 25)
{
chaine = chaine.substring(0,24);
}
else if (chaine.length <= 23)
{
chaine += a;
}
}
return chaine;
}
function envoit()
{
document.getElementById('btn').disabled = 'disabled';
var key = arrange(hex_md5(document.getElementById('clef_publique').value));
var message = document.getElementById('<?php echo $_SESSION['input_login']; ?>').value;
var encrypte = des (key, message, 1,0);
document.getElementById('<?php echo $_SESSION['input_login']; ?>').value = stringToHex(encrypte);
var keypass = arrange(document.getElementById('<?php echo $_SESSION['input_pass']; ?>').value + document.getElementById('clef_publique').value);
var messagepass = document.getElementById('<?php echo $_SESSION['input_pass']; ?>').value;
var encryptepass = des (keypass, messagepass, 1,0);
document.getElementById('<?php echo $_SESSION['input_pass']; ?>').value = stringToHex(encryptepass);
document.getElementById('formulaire').submit();
}
</script>
</head>
<body>
<?php
// on vérifie que le formulaire a bien été envoyé.
if ( isset ($_POST[$_SESSION['input_login']]) || isset ($_POST[$_SESSION['input_pass']]) )
{
// on vérifie que le formulaire a bien été envoyé.
if (empty($_POST[$_SESSION['input_login']]))
{
$_SESSION = array(); // vide les champs de la session
session_destroy(); // détruit la session
echo "ERREUR: Nom d'utilisateur manquant!"; // Un beau message!
echo "<meta http-equiv=refresh content=\"10; url=login.php\">"; // on redirige vers la page de login
exit();
}
// on vérifie que le formulaire a bien été envoyé.
if (empty($_POST[$_SESSION['input_pass']]))
{
$_SESSION = array(); // vide les champs de la session
session_destroy(); // détruit la session
echo "ERREUR: Mot de passe manquant!"; // Un beau message!
echo "<meta http-equiv=refresh content=\"10; url=login.php\">"; // on redirige vers la page de login
exit();
}
$clef = arrange(md5($_SESSION['clef_publique']));
$donnees_encryptees = hexToString($_POST[$_SESSION['input_login']]);
$utilisateur = trim(des ($clef, $donnees_encryptees, 0, 0, null));
$clef_privee = "la clef privée du serveur";
$clef_de_decryption = arrange(crypt($clef_privee,$utilisateur));
// Les parametres de connexion à MySQL.
$mysql_serveur = "Votre serveur MySQL"; //Normalement, "localhost"
$mysql_user = "Nom d'utilisateur MySQL";
$mysql_mot_de_passe = "Mot de passe MySQL";
$mysql_base_de_donnees = "Nom de la base de donnée";
//On ouvre la conexion au serveur MySQL de façon sécurisée afin de se protéger
// des injections SQL.
$connexion = mysql_connect ($mysql_serveur,$mysql_user,$mysql_mot_de_passe) or die ('Erreur connexion: '.mysql_error() );
if(!is_resource($connexion))
{
$_SESSION = array(); // vide les champs de la session
session_destroy(); // détruit la session
echo "Échec de la connexion au serveur\n";
//on retourne sur la page de login
echo "<meta http-equiv=refresh content=\"2; url=login.php\">";
exit();
}
else
{
if(get_magic_quotes_gpc())
{
$objet_de_recherche = stripslashes($utilisateur);
}
else
{
$objet_de_recherche = $username;
}
//On va chercher les informations nécessaires dans la table des utilisateurs
$requete = sprintf("SELECT * FROM `%s`.`nom_de_la_table`
WHERE `champ_login` = '%s' LIMIT 1;",
$mysql_base_de_donnees,
mysql_real_escape_string($objet_de_recherche, $connexion));
$resultats = mysql_query($requete, $connexion);
// Si la requête retourne quelque chose, c'est que l'utilisateur existe.
//Évidemment, lors de la création des utilisateurs, il faut s'assurer qu'ils sont uniques.
if (mysql_num_rows($resultats) == 1)
{
while ($data=mysql_fetch_array($resultats))
{
//On décrypte le mot de passe venant de la base de données
$mot_de_passe_encrypte_db = hexToString($data['champ_de_mot_de_passe']);
$mot_de_passe = des ($clef_de_decryption, $mot_de_passe_encrypte_db, 0, 0, null);
// On récupère en même temps les données nécessaires pour la session si le cas est.
$id = $data['champ_voulu'];
}
}
else
{
//la requête n'a pas trouvé l'utilisateur, donc il n'existe pas.
$_SESSION = array(); // vide les champs de la session
session_destroy(); // détruit la session
echo "ERREUR :<br> Nom d'utilisateur ou mot de passe incorrecte!"; //encore un beau message!
//on sur la page de login
echo "<meta http-equiv=refresh content=\"2; url=login.php\">";
exit();
}
}
$mot_de_passe_recu_encrypte = hexToString($_POST[$_SESSION['input_pass']]);
$clef_de_decryption = arrange(trim($mot_de_passe).$_SESSION['clef_publique']);
$mot_de_passe_recu_decrypte = des ($clef_de_decryption, $mot_de_passe_recu_encrypte, 0, 0, null);
if (trim($mot_de_passe) == trim($mot_de_passe_recu_decrypte))
{
//Les mots de passes sont pareils!
$_SESSION = array(); //On vide les informations actuelles de la session.
//on assigne aux variables sessions les informations nécessaires au fonctionnement du site.
$_SESSION['id_user'] = $id;
$_SESSION['login'] = $nom_utils;
echo "<h2>Accès autorisé!</h2><br />\n"; // ce que tout le monde veux voir comme message
echo "<h4>Vous allez être redirigé dans 2 secondes.</h4>\n"; // un dernier p'tit message avant les portes du paradis!
//on redirige l'utilisateur vers la page désirée.
echo "<meta http-equiv=refresh content=\"2; url=pagedesiree.php?PHPSESSID=".session_id()."\">";
}
else
{
// Les mots de passes ne sont pas identiques!
$_SESSION = array(); // vide les champs de la session
session_destroy(); // détruit la session
echo "ERREUR 2: Nom d'utilisateur ou mot de passe incorrecte!"; // un petit message redondant!
echo "<meta http-equiv=refresh content=\"10; url=login.php\">";
exit();
}
}
else
{
//Le formulaire n'a pas encore été envoyé.
?>
<form action="login.php" method="post" name="formulaire" target="_top" id="formulaire">
<table width="300" border="1" align="center" cellpadding="5" cellspacing="0">
<tr>
<td width="98">Utilisateur :</td>
<td width="176" align="center" valign="top">
<input type="text" size="20" id="<?php echo $_SESSION['input_login']; ?>" name="<?php echo $_SESSION['input_login']; ?>">
</td>
</tr>
<tr>
<td>Mot de passe :</td>
<td align="center" valign="top">
<input type="text" size="20" id="<?php echo $_SESSION['input_pass']; ?>" name="<?php echo $_SESSION['input_pass']; ?>">
</td>
</tr>
<tr align="center">
<td colspan="2">
<input type="hidden" name="clef_publique" id="clef_publique" value="<?php echo $_SESSION['clef_publique']; ?>">
<input type="button" name="btn" id="btn" value="Connexion" onclick="envoit();"/></td>
</td>
</tr>
</table>
</form>
<?php
}
?>
</body>
</html>
Voila!Si vous voyez une faille, n'hésitez pas a me le dire!
Merci!