這樣我們就是在登入時透過使用者輸入的password加上我們資料庫儲存的salt的值再透過hash去比對我們資料庫passwordhash的值是否一樣達到安全的目的
那我們該如何在asp.net mvc 重現呢 如下
首先建立我們的註冊會員model
public class User { [Key] public int RegistrationId { get; set; } //This will be primary key column with auto increment public string FirstName { get; set; } public string LastName { get; set; } public string UserName { get; set; } public string EmailId { get; set; } public string Password { get; set; } public string Gender { get; set; } public string VCode { get; set; } public DateTime CreateDate { get; set; } public DateTime ModifyDate { get; set; } public bool Status { get; set; } }隨自己喜好建立DB 我是用code first migrations update
public class CmsDbContext : DbContext { public DbSet寫個加密的helper要用的時候可以叫用ObjRegisterUser { get; set; } // Here User is the class }
public static class Helper { public static string ToAbsoluteUrl(this string relativeUrl) //Use absolute URL instead of adding phycal path for CSS, JS and Images { if (string.IsNullOrEmpty(relativeUrl)) return relativeUrl; if (HttpContext.Current == null) return relativeUrl; if (relativeUrl.StartsWith("/")) relativeUrl = relativeUrl.Insert(0, "~"); if (!relativeUrl.StartsWith("~/")) relativeUrl = relativeUrl.Insert(0, "~/"); var url = HttpContext.Current.Request.Url; var port = url.Port != 80 ? (":" + url.Port) : String.Empty; return String.Format("{0}://{1}{2}{3}", url.Scheme, url.Host, port, VirtualPathUtility.ToAbsolute(relativeUrl)); } public static string GeneratePassword(int length) //length of salt { const string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789"; var randNum = new Random(); var chars = new char[length]; var allowedCharCount = allowedChars.Length; for (var i = 0; i <= length - 1; i++) { chars[i] = allowedChars[Convert.ToInt32((allowedChars.Length) * randNum.NextDouble())]; } return new string(chars); } public static string EncodePassword(string pass, string salt) //encrypt password { byte[] bytes = Encoding.Unicode.GetBytes(pass); byte[] src = Encoding.Unicode.GetBytes(salt); byte[] dst = new byte[src.Length + bytes.Length]; System.Buffer.BlockCopy(src, 0, dst, 0, src.Length); System.Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); byte[] inArray = algorithm.ComputeHash(dst); //return Convert.ToBase64String(inArray); return EncodePasswordMd5(Convert.ToBase64String(inArray)); } public static string EncodePasswordMd5(string pass) //Encrypt using MD5 { Byte[] originalBytes; Byte[] encodedBytes; MD5 md5; //Instantiate MD5CryptoServiceProvider, get bytes for original password and compute hash (encoded password) md5 = new MD5CryptoServiceProvider(); originalBytes = ASCIIEncoding.Default.GetBytes(pass); encodedBytes = md5.ComputeHash(originalBytes); //Convert encoded bytes back to a 'readable' string return BitConverter.ToString(encodedBytes); } public static string base64Encode(string sData) // Encode { try { byte[] encData_byte = new byte[sData.Length]; encData_byte = System.Text.Encoding.UTF8.GetBytes(sData); string encodedData = Convert.ToBase64String(encData_byte); return encodedData; } catch (Exception ex) { throw new Exception("Error in base64Encode" + ex.Message); } } public static string base64Decode(string sData) //Decode { try { var encoder = new System.Text.UTF8Encoding(); System.Text.Decoder utf8Decode = encoder.GetDecoder(); byte[] todecodeByte = Convert.FromBase64String(sData); int charCount = utf8Decode.GetCharCount(todecodeByte, 0, todecodeByte.Length); char[] decodedChar = new char[charCount]; utf8Decode.GetChars(todecodeByte, 0, todecodeByte.Length, decodedChar, 0); string result = new String(decodedChar); return result; } catch (Exception ex) { throw new Exception("Error in base64Decode" + ex.Message); } } }然後我們最重要得Controller
public ActionResult Registration() { return View(); } [ValidateAntiForgeryToken] [HttpPost] public ActionResult Registration(User objNewUser) { try { using(var context = new CmsDbContext()) { var chkUser = (from s in context.ObjRegisterUser where s.UserName == objNewUser.UserName || s.EmailId == objNewUser.EmailId select s).FirstOrDefault(); if (chkUser == null) { var keyNew = Helper.GeneratePassword(10); var password = Helper.EncodePassword(objNewUser.Password, keyNew); objNewUser.Password = password; objNewUser.CreateDate = DateTime.Now; objNewUser.ModifyDate = DateTime.Now; objNewUser.VCode = keyNew; context.ObjRegisterUser.Add(objNewUser); context.SaveChanges(); ModelState.Clear(); return RedirectToAction("LogIn", "Login"); } ViewBag.ErrorMessage = "User Allredy Exixts!!!!!!!!!!"; return View(); } } catch (Exception e) { ViewBag.ErrorMessage = "Some exception occured" + e; return View(); } }最後我們登入需要解密去對應我們DB的hash
public ActionResult Login() { return View(); } [ValidateAntiForgeryToken] [HttpPost] public ActionResult LogIn(string userName, string password) { try { using(var context = new CmsDbContext()) { var getUser = (from s in context.ObjRegisterUser where s.UserName == userName || s.EmailId == userName select s).FirstOrDefault(); if (getUser != null) { var hashCode = getUser.VCode; //Password Hasing Process Call Helper Class Method var encodingPasswordString = Helper.EncodePassword(password, hashCode); //Check Login Detail User Name Or Password var query = (from s in context.ObjRegisterUser where(s.UserName == userName || s.EmailId == userName) && s.Password.Equals(encodingPasswordString) select s).FirstOrDefault(); if (query != null) { //RedirectToAction("Details/" + id.ToString(), "FullTimeEmployees"); //return View("../Admin/Registration"); url not change in browser return RedirectToAction("Index", "Admin"); } ViewBag.ErrorMessage = "Invallid User Name or Password"; return View(); } ViewBag.ErrorMessage = "Invallid User Name or Password"; return View(); } } catch (Exception e) { ViewBag.ErrorMessage = " Error!!! contact cms@info.in"; return View(); } }