2017-08-16 1 views
0

Je suis en train d'écrire un programme ASP.NET où j'ai besoin de stocker le mot de passe des utilisateurs dans la base de données. Mais je reçois un mot de passe incompatibles quand je compare le mot de passe de la base de données avec le mot de passe d'entrée de l'utilisateur. Même si le mot de passe des utilisateurs est correct.Comment saler et comparer mot de passe dans ASP.NET MVC

Hashage:

string PasswordSalt = Crypto.HashPassword(DateTime.Now.ToString()); 
string hashPassword = Crypto.HashPassword(formcollection["PassWord"]); //Hash User PassWord 
user.PassWord = Crypto.HashPassword(PasswordSalt + hashPassword);//Add Salt to Password For Futher Security 
user.PassWordSalt = PasswordSalt; 

Mot de passe Vérification:

Users ThisUser = Users.UsersGetByEmail((string)Session["email"]); 
string checkpassword = ThisUser.PassWord; 

//User Inputed password. 
string password = user.PassWord; 

if (password != null) 
{ 
    //Need to fix. 
    string encrypt_password = Crypto.HashPassword(password); 
    string salted_password = Crypto.HashPassword(ThisUser.PassWordSalt + encrypt_password); 
    //bool does_password_match = Crypto.VerifyHashedPassword(checkpassword, password); 
    if (checkpassword == salted_password) 
    { 
     //Check if the inputed password matches the password from the Database. 

     //Remember to give session based on the user_id. 
     Session["user_id"] = ThisUser.Id; 
     return RedirectToAction("Promise"); 


    } 
    else 
    { 

     ModelState.AddModelError("PassWord", "Wrong Password, Please Enter Correct Password"); 
     return View(user); 
    } 
+0

avez-vous envisagé d'utiliser l'identité d'asp? tout cela est pris en charge pour vous avec beaucoup de méthodes intégrées –

+1

Règle 1 sur la sécurité: ne le construisez pas vous-même :) – oerkelens

Répondre

1

Je ne l'ai jamais utilisé, mais d'après la documentation ...

Crypto.HashPassword ajoute le sel pour et renvoie une chaîne codée en base 64 avec tous les détails pour vérifier le mot de passe. Donc, vous n'avez pas besoin d'ajouter un sel vous-même. Il vous suffit de stocker le résultat du hachage (base64EncodedHash ci-dessous) dans la base de données, puis de l'utiliser avec VerifyHashedPassword pour vous authentifier plus tard. Par exemple. faire un test unitaire comme ceci:

var base64EncodedHash = Crypto.HashPassword("password"); 
Assert.IsTrue(Crypto.VerifyHashedPassword(base64EncodedHash, "password")); 
Assert.IsFalse(Crypto.VerifyHashedPassword(base64EncodedHash, "otherPass")); 

https://msdn.microsoft.com/en-us/library/system.web.helpers.crypto.verifyhashedpassword(v=vs.111).aspx

Pour traduire à votre code:

user.PassWord = Crypto.HashPassword(formcollection["PassWord"]); 

ensuite à vérifier (les commentaires ajoutés pour bizarreries je vois):

//Why are you storing "email" in Session before user is validated??? Seems off. 
Users ThisUser = Users.UsersGetByEmail((string)Session["email"]); 
string userInputPassword = user.PassWord; //this should be coming from POST 

if(ThisUser != null && Crypto.VerifyHashedPassword(ThisUser.PassWord, userInputPassword)) { 
    Session["user_id"] = ThisUser.Id; 
    return RedirectToAction("Promise"); 
} 
else { 
    ModelState.AddModelError("PassWord","Your username or password are incorrect"); 
    return View(user); 
} 

Idéalement, comme je l'ai un peu indiqué par mon changement de votre texte d'erreur ... vous voulez également donner à l'utilisateur le même message d'erreur si le nom d'utilisateur/email ou mot de passe sont faux. Votre code, tel quel, renvoie probablement une erreur différente si l'e-mail ne renvoie pas de compte, mais vous ne voulez pas donner autant d'informations aux attaquants à force brute.

Vous devez également mettre en une force brute de vérification de sorte que s'ils tentent trop de fois avec des échecs, bloquer cette adresse IP pour un montant X de temps., Etc.

Et, comme quelqu'un l'a dit ... quand il s'agit de la sécurité ... jusqu'à ce que vous êtes l'expert ... il est préférable d'utiliser le code/cadres préexistants pour vous atténuer les risques .

+0

J'adorerai mettre en œuvre la vérification de la force brute. Une idée sur la façon de s'y prendre? Merci d'avoir répondu. – Izuagbala

+0

@Izuagbala, Pour la vérification de la force brute, tout ce que vous essayez de faire est de les ralentir pour qu'un bon mot de passe prenne des centaines d'années à deviner. Un quick-google devrait vous donner beaucoup d'explications complètes. Cependant, en un mot: 1) faire table DB ou cache IpLogAttempts {Ip, AttemptsCount, LastAttempt}. 2) Lorsque l'IP tente de se connecter, bloquez-la si elle est dépassée. 3) Si ce n'est pas encore bloqué, vérifiez le mot de passe et si le login est faux, augmentez votre AttemptsCount. Même le blocage d'une adresse IP pendant 5 à 20 minutes réduit considérablement les chances d'une attaque par force brute réussie. –

+0

@Izuagbala, voici une explication plus approfondie que j'ai jeté ensemble puisque les commentaires ne sont pas assez d'espace pour expliquer tout cela: http://coding.xingcr.com/securing-website-against-brute-force-attacks/ –