Si votre hébergeur le permet, ou si vous devrez gérer des données sensibles, utilisez HTTPS, point final. (C'est souvent requis par la loi afaik).
Sinon, si vous voulez faire quelque chose via HTTP. Je ferais quelque chose comme ça.
- Le serveur intègre sa clé publique dans la page de connexion.
- Le client remplit le formulaire de connexion et clique sur Soumettre.
- Une requête AJAX obtient l'horodatage actuel du serveur.
- Le script côté client concatène les informations d'identification, l'horodatage et un sel (haché à partir de données analogiques, par exemple les mouvements de la souris, les événements de pression de touche), le chiffre à l'aide de la clé publique.
- Soumet le hachage résultant.
- Le serveur déchiffre le hachage
- Vérifie si l'horodatage est suffisamment récent (autorise une courte fenêtre de 5 à 10 secondes uniquement). Rejette la connexion si l'horodatage est trop ancien.
- Stocke le hachage pendant 20 secondes. Rejette le même hachage pour la connexion pendant cet intervalle.
- Authentifie l'utilisateur.
Ainsi, le mot de passe est protégé et le même hachage d'authentification ne peut pas être rejoué.
À propos de la sécurité du jeton de session. C'est un peu plus difficile. Mais il est possible de rendre la réutilisation d'un jeton de session volé un peu plus difficile.
- Le serveur définit un cookie de session supplémentaire qui contient une chaîne aléatoire.
- Le navigateur renvoie ce cookie à la prochaine demande.
- Le serveur vérifie la valeur dans le cookie, si elle est différente, alors il détruit la session, sinon tout va bien.
- Le serveur redéfinit le cookie avec un texte différent.
Ainsi, si le jeton de session a été volé et qu'une demande est envoyée par quelqu'un d'autre, à la prochaine demande de l'utilisateur d'origine, la session sera détruite. Donc, si l'utilisateur navigue activement sur le site, en cliquant souvent sur des liens, le voleur n'ira pas loin avec le jeton volé. Ce schéma peut être renforcé en exigeant une autre authentification pour les opérations sensibles (comme la suppression de compte).
EDIT: Veuillez noter que cela n'empêche pas les attaques MITM si l'attaquant configure sa propre page avec une clé publique différente et envoie des requêtes proxy au serveur. Pour se protéger contre cela, la clé publique doit être épinglée dans le stockage local du navigateur ou dans l'application pour détecter ce type d'astuces.
À propos de l'implémentation: RSA est probablement l'algorithme le plus connu, mais il est assez lent pour les longues clés. Je ne sais pas à quelle vitesse une implémentation PHP ou Javascript serait. Mais il existe probablement des algorithmes plus rapides.