Bonsoir,
Attention,
base64_encode() ne crypte pas, il encode et
base64_decode() te redonne en clair ce qui est encoder. Cela peut te servir a cacher visuellement une URL, mais pour un mot de passe ça revient à le stocké en clair.
Pour crypter en php tu as plusieurs pistes :
https://www.php.net/manual/fr/book.password.php /
https://www.php.net/manual/fr/faq.passwords.php
https://www.php.net/manual/en/function.hash.php
https://www.php.net/manual/fr/function.sha1.php
https://www.php.net/manual/fr/function.md5.php
_____________________________________________________________
https://www.php.net/manual/fr/function.base64-encode.php
https://www.php.net/manual/fr/function.base64-decode.php
il y a aussi
https://www.php.net/manual/fr/function.urlencode.php
et puis tu peux aussi générer "un grain de sel" pour rendre le plus unique possible cette chaine de caractère que tu veut crypter.
Il existe des dictionnaires de mots et leurs équivalent cryptés qui ne cessent de s'agrandir au fil du temps.
Ce qui fait qu'en utilisant une méthode seule, une chaine de caractères retournera toujours la même chaine cryptée. En lançant en boucle un programme qui génère des chaines de mots ou caractères aléatoires qui sont stockée avec leur équivalent crypté, le
supermotdepassekamoi finira par apparaitre dans ce foutu dico.
L'ajout d'une chaine de caractères aléatoires (l’assaisonnement) à la chaine crypté rend la probabilité de voir ce mot figuré au dico s’amoindrir.
Tu peut par exemple faire un mix : ajouté un grain de sel a la chaine a cryptée et imbriqué 2 modes de cryptage
moyen pour obtenir un cryptage suffisamment costaud.
En faisant cela, il te faudra stocké le grain de sel et la chaine crypté.
Pour vérifier la chaine , il faut réutiliser son grain de sel et le cryptage et comparé ce résultat avec la chaine cryptée déjà stockée .
En cas de mot de passe perdu, il est impossible de retrouvé le mot de passe, il faut en généré un nouveau. Ce lien temporaire envoyé sur une adresse mail , donnée au moment de l'inscription ou figurant dans les données de l'utilisateur peut-être encode en base64 pour y cacher quelque données utiles à reconnaitre le membre et une valeur cryptée de référence , ou bien seule la valeur cryptée enregistrée dans les données du membre que l'on recherchera en bdd.
Voici un exemple (A NE PAS UTILISER TEL QUEL) qui utilise encode64()/decode64() pour le lien d'activation/récupération qui sera visible encodé dans le mail
mais au final en clair , et la génération d'un grain de sel ajouter à une date cryptée en imbriquant
sha1( 'grain_de_sel'. md5('la_date_a_cacher')) . Ce n'est pas incraquable, mais les ressources à mettre en œuvre n'en valent vraiment pas le coup, c'est pas les coffres de forknox
.
Voici donc l'exemple qui se base sur un fichier texte (au lieu d'une bdd) pour une démo.
! Ce n'est qu'une démo sans bonnes pratiques, juste pour montrer l'idée évoquée précédemment à propos d'un lien temporaire , je crois que ça couvre pas trop mal un déroulé possible.
<?php // NE pas utiliser en vrai - methode obsolete et codage à l'arrache, c'est juste une démo d'exemple / voir https://www.php.net/manual/fr/function.password-verify.php une fois l'intêret du stockage d'un mot passe crypté
if(isset($_GET['monCompte'])) {
$seeyou = base64_decode($_GET['monCompte']);
header("location: http://".$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'].$seeyou );
}
?>
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title> test</title>
<meta name="description" content=" test valid connexion ">
<meta name="author" content="MyPc">
<link rel="stylesheet" href="css/styles.css?v=1.0">
</head>
<style>
body{display:grid;justify-content:center;}
</style>
<body>
<h1 style="width:max-content;margin:1em auto;max-width:80%;">test generation lien connexion temporaire</h1>
<?php
if(isset($_POST['pwd1'])) {
$mdp = $_POST['pwd1'];
$mdp64 = base64_encode($mdp);
$mdpdec64 = base64_decode($mdp64);
$mdp_md5 = md5($mdp);
$mdp_sha1 = sha1($mdp);
$clef_de_sel = 'UneChaineAuHasard'; // soit generation aléatoire ou par exemple prit dans les infos fournit par le membre (date d'inscription,pseudo,nbre de connexions,n] d'enregistrement , mail, etc selon votre imagination)
$mdp64_sel = base64_encode($mdp.$clef_de_sel);
$mdpdec64_sel =str_replace($clef_de_sel, '',base64_decode( $mdp64_sel));
$mdp_md5_sel = md5($mdp.$clef_de_sel);
$mdp_sha1_sel = sha1($mdp.$clef_de_sel);
$mdp_sha1_md5_sel =sha1(md5($mdp).$clef_de_sel); // ou sha1($clef_de_sel.md5($mdp)) ou sha1($clef_de_sel.md5($mdp$clef_de_sel.)) ....
$mdp_md5_sha1_sel =md5(sha1($mdp).$clef_de_sel); // ou md5($clef_de_sel.sha1($mdp)) ou md5($clef_de_sel.sha1($mdp$clef_de_sel.)) ....
echo '<style>table,td ,th {border:solid 1px;text-align:center;padding:0.15em;} th {background:lightgray}.oups{color:crimson;background:yellow}</style>
<p><b>Il n\'y a rien eu d\'enregistrer durant cette étape de l\'exemple</b>, mais voici quelques possibilités , <b>pour sécuriser un mot de passe il ne faut pas utiliser une méthode reversible</b>.</p>
<table>
<thead>
<tr><th> mot de passe</th> <th> hachoir </th><th>chaine modifiée à stockée</th><th> decodage natif disponible </th><th>résultat </th><th>grain de sel </th></tr>
</thead>
<tbody>
<tr><th rowspan="8">'.$mdp.'</td><td>base64_encode("pwd") </td><td>'.$mdp64.' </td><td> base64_decode() </td><td class="oups">'.$mdpdec64.' </td><td> non </td></tr>
<tr> <td>base64_encode("pwd + sel" ) </td><td>'.$mdp64_sel.' </td><td> str_replace(sel, "",base64_decode(chainee salée))</td><td class="oups">'.$mdpdec64_sel.' </td><td rowspan=" ">'.$clef_de_sel.' </td></tr>
<tr> <td>md5("pwd") </td><td>'.$mdp_md5.' </td><td> non </td><td>aucun sans hachage </td><td rowspan=" ">non </td></tr>
<tr> <td>sha1("pwd") </td><td>'.$mdp_sha1.' </td><td> non </td><td>aucun sans hachage </td><td rowspan=" 5 ">'.$clef_de_sel.'</td></tr>
<tr> <td>md5("pwd + sel") </td><td>'.$mdp_md5_sel.' </td><td> non </td><td>aucun sans hachage </td> </tr>
<tr> <td>sha1("pwd + sel") </td><td>'.$mdp_sha1_sel.' </td><td> non </td><td>aucun sans hachage </td> </tr>
<tr> <td>sha1(md5("pwd + sel") </td><td>'.$mdp_sha1_md5_sel.' </td><td> non </td><td>aucun sans hachage </td> </tr>
<tr> <td>md5(sha1("pwd + sel") </td><td>'.$mdp_md5_sha1_sel.' </td><td> non </td><td>aucun sans hachage </td> </tr>
</tbody>
</table>
<p>Si grain de sel, il vaut mieux que celui-ci soit unique à chaque enregistrement , il faut donc le stocker avec la chaine modifié</p>
<p><a href="http://'.$_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME'].'">Retour au formulaire</a></p>
</body>
</html>';
exit;
}
$date=date("Y-m-d");
$duree ="+2day";
if(isset($_POST['duree'])){$duree=$_POST['duree'];}
$lastValidDate = strtotime($duree, strtotime($date));
if(isset($_POST['name'])) {
echo '<p>demande enregistrée en attente d\'activation</p>';
$salt = '';
$chaine = 'abcdefghijklmnpqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
mt_srand((float)microtime()*1000000);
for($i=0; $i<10; $i++) $salt .= $chaine[ mt_rand()%strlen($chaine) ];
$limit=sha1($salt.md5($lastValidDate));
$filelimit=$date;
$nom =$_POST['name'];
$prenom =$_POST['nickname'];
$fileMember= $prenom.'.'.$nom.'.quand';
$fileMemberContent= $salt.','.$date .','.$duree;
$open = fopen($fileMember, "w") ;
fwrite($open, $fileMemberContent);
fclose($open);
$lien = '?p='.$nom.'&pr='.$prenom.'&val='.$limit ;
$secret= base64_encode($lien);
$lienValidationEnAttente = $_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME'].'?monCompte='.$secret ;
echo '<p> Pour finaliser votre inscription veuillez créer votre mot de passe en suivant ce lien:<br> <a href="http://'.$lienValidationEnAttente.'">Activer mon espace personnel</a>.</p>';
}
if(isset($_GET['p']) && isset($_GET['pr']) && isset($_GET['val']) ) {
echo '<p>Bienvenue <b style="text-transform:uppercase">'.$_GET['pr'].' '.$_GET['p'].'</b>.</p>';
if(@$open = fopen($_GET['pr'].'.'.$_GET['p'].'.quand', "r")) {
while (($data = fgetcsv($open, 100, ",")) !== FALSE) {
$array[] = $data;
}
fclose($open);
foreach($array as $i => $line){
$end = strtotime($line[2], strtotime($line[1]));
$check=sha1($line[0].md5($end));
//verif de la date de validité
if ($check == $_GET['val']) {
// la date est elle dépasée ?
$dnow = strtotime($date);
if (($dnow < $end) || ($dnow == $end)) {
echo '<form action="" method="post" style="display:grid;justify-content:center;">
<fieldset>
<legend style="text-transform:uppercase">Mise à jour du mot de passe</legend>
<div style="display:grid;grid-template-columns:auto auto;gap:0.5em;justify-content:center;">
<label>Votre nouveau mot de passe</label>
<input name="pwd1">
<label>Retaper votre mot de passe</label>
<input name="pwd2">
<input type="submit">
</div>
</fieldset>
</form>';
unlink($_GET['pr'].'.'.$_GET['p'].'.quand');
}
else { echo 'Ce lien a expiré, veuillez renouveler votre demande d\'inscription';}
}
}
} else { echo '<p style="color:orange">Il n`y a actuellement aucune demande au nom de <b style="text-transform:uppercase"> '.$_GET['pr'].' '.$_GET['p'].' </b> en attente de finalisation. </p>'; }
}
?>
<?php if((empty($_POST)) && (empty($_GET))) {?>
<form action="" method="post" style="display:grid;justify-content:center;">
<fieldset>
<legend style="text-transform:uppercase">Demande d'nscription</legend>
<div style="display:grid;grid-template-columns:auto auto;gap:0.5em;justify-content:center;">
<label for="name">Nom</label>
<input type="text" name="name">
<label for="nickname">Prénom</label>
<input type="text" name="nickname">
<label for="mail">Courriel</label>
<input type="email" name="mail">
<label for="duree">validité</label>
<select name="duree">
<option value="-1 month">test date expirée</option>
<option value="+1 day">1 journée</option>
<option value="+2 day" selected>2 jours</option>
<option value="+10 day">10 jours</option>
<option value="+1 month">1 mois</option>
<option value="+1 year">1 ans</option>
</select>
<input type="submit">
</div>
</fieldset>
</form>
<?php } ?>
<p><a href="http://<?php echo $_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME'].'">Retour au formulaire</a></p>'; ?>
</body>
</html>
Cdt
Modifié par gcyrillus (25 Sep 2021 - 14:25)