ASP.NET MVC結(jié)合JavaScript登錄、校驗(yàn)和加密
最近閑來無事給自己寫了家庭財(cái)務(wù)收支管理系統(tǒng),也就包含支出管理,收入管理和一些統(tǒng)計(jì)功能。
先說登錄模塊,因?yàn)樯婕癎ET和POST請(qǐng)求,這些東西都是能被監(jiān)控和抓取的所以就考慮這使用RSA加密解密方式傳輸用戶名和密碼參數(shù),頁面JS如下:
/*需要引入三個(gè)JS文件,BigInt.js、RSA.js和Barrett.js,用到cookie則需要引入jquery.cookie.js文件*/ //與后臺(tái)交互獲取公鑰 function getPublicKey() { var pubKey = ''; if ($.cookie('publicKey') == null) { $.ajax({ url: "/Account/GetRsaPublicKey", type: "get", contentType: "application/x-www-form-urlencoded; charset=utf-8", async: false, data: {}, dataType: "json", success: function (data) { if (data.Code == 0) { pubKey = data.RsaPublicKey + "," + data.Key; $.cookie('publicKey', pubKey, { expires: 1 / 1440 }); } else { Config.Method.JudgeCode(data, 1); } } }); } else { pubKey = $.cookie('publicKey'); } return pubKey; } //公鑰加密用戶密碼Pwd為RSA加密后參數(shù) function rsaEncrypt(pwd) { var publicKey = getPublicKey(); setMaxDigits(129); var rsaKey = new RSAKeyPair(publicKey.split(",")[0], "", publicKey.split(",")[1]); var pwdRtn = encryptedString(rsaKey, pwd); return pwdRtn + "," + publicKey.split(",")[2]; } //POST登錄請(qǐng)求,參數(shù) <script type="text/javascript"> $(function () { $('#btnSubmit').live('click', function () { var uName = $('#u').val(); var pwd = $('#p').val(); if (uName == '') { alert('用戶名不能為空'); return; } if (pwd == '') { alert('用戶密碼不能為空'); return; } var enPwd = rsaEncrypt(pwd); $.ajax({ type: "POST", url: "/Account/UserLogin", data: { 'UserName': uName, 'Pwd': enPwd.split(",")[0], 'Key': enPwd.split(",")[1], 'RUrl': $('#hiddenUrl').val() }, contentType: "application/x-www-form-urlencoded; charset=utf-8", async: false, dataType: "json", success: function (data) { if (data.result == true) { window.location.href = data.url; return false; } else { $('#msg').text(data.message); } }, error: function (XMLHttpRequest, textStatus, errorThrown) { $('#msg').text(XMLHttpRequest.status + '||' + XMLHttpRequest.readyState + '||' + textStatus); } }); }); }) </script>
前臺(tái)加密完成后就需要后臺(tái)做解密處理,解密完成后需要使用MD5加密現(xiàn)有密碼與數(shù)據(jù)庫中用戶密碼進(jìn)行比較驗(yàn)證,如果驗(yàn)證通過則需要寫入cookie以便下次用戶能自 動(dòng)登錄,由于cookie中我不希望用戶名和密碼都明碼存儲(chǔ),我這里用到了AES加密的方式,自定義一個(gè)32位的加密密鑰對(duì)cookie進(jìn)行加密解密處理,后臺(tái)c#代碼如下:
[HttpPost] public JsonResult UserLogin(string UserName, string Pwd, string Key, string RUrl) { string privateKey = Common.CacheGet(Key) as string; if (!string.IsNullOrEmpty(privateKey)) { if (string.IsNullOrEmpty(UserName)) { return Json(new { result = false, message = "用戶名為空" }, JsonRequestBehavior.AllowGet); } if (string.IsNullOrEmpty(Pwd)) { return Json(new { result = false, message = "用戶密碼為空" }, JsonRequestBehavior.AllowGet); } string pwd = Common.DecryptRSA(Pwd, privateKey);//私鑰解密 string md5Pwd = Common.NoneEncrypt(Common.NoneEncrypt(Common.NoneEncrypt(pwd, 1), 1), 1);//將解密后的值md5加密3次 AccountUnserInfo userInfo = bll.GetUserInfo(UserName.Trim(), md5Pwd); if (userInfo != null && userInfo.U_Id > 0)//用戶信息存在 { //用戶名、密碼放入cookie HttpCookie cookie = new HttpCookie("fw_izz"); //AES加密Cookie cookie["u_name"] = AesEncryptHelper.EncryptAes(UserName); cookie["u_pwd"] = AesEncryptHelper.EncryptAes(pwd); cookie.Expires = DateTime.Now.AddDays(7); Response.Cookies.Add(cookie); if (!string.IsNullOrEmpty(RUrl))//接收隱藏域中的值 { return Json(new { result = true, message = "成功", url = RUrl }); } else { return Json(new { result = true, message = "成功", url = "/AccountDetail/Index" }); } } else { return Json(new { result = false, message = "用戶信息不存在", url = "/Account/Index" }); } } else { return Json(new { result = false, message = "非法秘鑰", url = "/Account/Index" }); } }
各種加密解密方法、Cache操作以及cookie操作代碼如下:
public class Common { /// <summary> /// 產(chǎn)生一組RSA公鑰、私鑰 /// </summary> /// <returns></returns> public static Dictionary<string, string> CreateRsaKeyPair() { var keyPair = new Dictionary<string, string>(); var rsaProvider = new RSACryptoServiceProvider(1024); RSAParameters parameter = rsaProvider.ExportParameters(true); keyPair.Add("PUBLIC", BytesToHexString(parameter.Exponent) + "," + BytesToHexString(parameter.Modulus)); keyPair.Add("PRIVATE", rsaProvider.ToXmlString(true)); return keyPair; } /// <summary> /// RSA解密字符串 /// </summary> /// <param name="encryptData">密文</param> /// <param name="privateKey">私鑰</param> /// <returns>明文</returns> public static string DecryptRSA(string encryptData, string privateKey) { string decryptData = ""; try { var provider = new RSACryptoServiceProvider(); provider.FromXmlString(privateKey); byte[] result = provider.Decrypt(HexStringToBytes(encryptData), false); ASCIIEncoding enc = new ASCIIEncoding(); decryptData = enc.GetString(result); } catch (Exception e) { throw new Exception("RSA解密出錯(cuò)!", e); } return decryptData; } private static string BytesToHexString(byte[] input) { StringBuilder hexString = new StringBuilder(64); for (int i = 0; i < input.Length; i++) { hexString.Append(String.Format("{0:X2}", input[i])); } return hexString.ToString(); } public static byte[] HexStringToBytes(string hex) { if (hex.Length == 0) { return new byte[] { 0 }; } if (hex.Length % 2 == 1) { hex = "0" + hex; } byte[] result = new byte[hex.Length / 2]; for (int i = 0; i < hex.Length / 2; i++) { result[i] = byte.Parse(hex.Substring(2 * i, 2), System.Globalization.NumberStyles.AllowHexSpecifier); } return result; } private static ObjectCache Cache { get { return MemoryCache.Default; } } /// <summary> /// 獲取緩存 /// </summary> /// <param name="key"></param> /// <returns></returns> public static object CacheGet(string key) { return Cache[key]; } /// <summary> /// 設(shè)置緩存 /// </summary> /// <param name="key"></param> /// <param name="data"></param> /// <param name="cacheTime"></param> public static void CacheSet(string key, object data, int cacheTime) { CacheItemPolicy policy = new CacheItemPolicy(); policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime); Cache.Add(new CacheItem(key, data), policy); } /// <summary> /// 判斷緩存是否存在 /// </summary> /// <param name="key"></param> /// <returns></returns> public static bool IsSet(string key) { return (Cache[key] != null); } /// <summary> /// 緩存失效 /// </summary> /// <param name="key"></param> public static void CacheRemove(string key) { Cache.Remove(key); } /// <summary> /// 對(duì)字符串進(jìn)行加密(不可逆) /// </summary> /// <param name="Password">要加密的字符串</param> /// <param name="Format">加密方式,0 is SHA1,1 is MD5</param> /// <returns></returns> public static string NoneEncrypt(string Password, int Format) { string strResult = ""; switch (Format) { case 0: strResult = FormsAuthentication.HashPasswordForStoringInConfigFile(Password, "SHA1"); break; case 1: strResult = FormsAuthentication.HashPasswordForStoringInConfigFile(Password, "MD5"); break; default: strResult = Password; break; } return strResult; } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Asp.net 連接MySQL的實(shí)現(xiàn)代碼[]
ASP.NET連接MySQL需要一個(gè)組件(.net本身不提供訪問MySQL的驅(qū)動(dòng))MySQL.Data.Dll,此為官方提供(純C#開發(fā),開源噢),有多個(gè)版本選擇,采用的數(shù)據(jù)訪問模式為ADO.NET,跟asp.net訪問sqlserver很像,非常簡(jiǎn)單。2009-08-08.NET與樹莓派控制彩色燈帶WS28XX的實(shí)現(xiàn)
這篇文章主要為大家介紹了.NET與樹莓派控制彩色燈帶WS28XX的實(shí)現(xiàn)過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04jQuery Data Linking 對(duì)象與對(duì)象之間屬性的關(guān)聯(lián)
ASP.NET團(tuán)隊(duì)最近還向jQuery社區(qū)提交了被稱為data linking的技術(shù),Data Linking可以幫助你實(shí)現(xiàn)對(duì)象與對(duì)象之間屬性的關(guān)聯(lián)——當(dāng)其中一方發(fā)生改變時(shí)另一方也隨之改變。2010-12-12運(yùn)行asp.net時(shí)出現(xiàn) http錯(cuò)誤404-文件或目錄未找到
問題描述: http錯(cuò)誤404-文件或目錄未找到的解決方法2009-03-03JQuery實(shí)現(xiàn)Repeater無刷新批量刪除(附后臺(tái)asp.net源碼)
JQuery實(shí)現(xiàn)Repeater無刷新批量刪除(附后臺(tái)asp.net源碼) ,學(xué)習(xí)jquery的朋友可以參考下。2011-09-09.net 運(yùn)用二進(jìn)制位運(yùn)算進(jìn)行數(shù)據(jù)庫權(quán)限管理
.net 運(yùn)用二進(jìn)制位運(yùn)算進(jìn)行數(shù)據(jù)庫權(quán)限管理 ,需要的朋友可以參考一下2013-02-02一個(gè).net 壓縮位圖至JPEG的實(shí)例代碼
這篇文章介紹了.net 壓縮位圖至JPEG的實(shí)例代碼,有需要的朋友可以參考一下2013-11-11