你的位置:首页 > ASP.net教程

[ASP.net教程]ASP.NET MVC结合JavaScript登录、校验和加密


  最近闲来无事给自己写了家庭财务收支管理系统,也就包含支出管理,收入管理和一些统计功能。

  先说登录模块,因为涉及GET和POST请求,这些东西都是能被监控和抓取的所以就考虑这使用RSA加密解密方式传输用户名和密码参数,页面JS如下:

 
 1 /*需要引入三个JS文件,BigInt.js、RSA.js和Barrett.js,用到cookie则需要引入jquery.cookie.js文件*/ 2 //与后台交互获取公钥 3 function getPublicKey() { 4   var pubKey = ''; 5   if ($.cookie('publicKey') == null) { 6     $.ajax({ 7       url: "/Account/GetRsaPublicKey", 8       type: "get", 9       contentType: "application/x-www-form-urlencoded; charset=utf-8",10       async: false,11       data: {},12       dataType: "json",13       success: function (data) {14         if (data.Code == 0) {15           pubKey = data.RsaPublicKey + "," + data.Key;16           $.cookie('publicKey', pubKey, { expires: 1 / 1440 });17         } else {18           Config.Method.JudgeCode(data, 1);19         }20       }21     });22   } else {23     pubKey = $.cookie('publicKey');24   }25   return pubKey;26 }27 //公钥加密用户密码Pwd为RSA加密后参数28 function rsaEncrypt(pwd) {29   var publicKey = getPublicKey();30   setMaxDigits(129);31   var rsaKey = new RSAKeyPair(publicKey.split(",")[0], "", publicKey.split(",")[1]);32   var pwdRtn = encryptedString(rsaKey, pwd);33   return pwdRtn + "," + publicKey.split(",")[2];34 }35 //POST登录请求,参数36 <script type="text/javascript">37   $(function () {38     $('#btnSubmit').live('click', function () {39       var uName = $('#u').val();40       var pwd = $('#p').val();41       if (uName == '') {42         alert('用户名不能为空');43         return;44       }45       if (pwd == '') {46         alert('用户密码不能为空');47         return;48       }49       var enPwd = rsaEncrypt(pwd);50       $.ajax({51         type: "POST",52         url: "/Account/UserLogin",53         data: { 'UserName': uName, 'Pwd': enPwd.split(",")[0], 'Key': enPwd.split(",")[1], 'RUrl': $('#hiddenUrl').val() },54         contentType: "application/x-www-form-urlencoded; charset=utf-8",55         async: false,56         dataType: "json",57         success: function (data) {58           if (data.result == true) {59             window.location.href = data.url;60             return false;61           } else {62             $('#msg').text(data.message);63           }64         },65         error: function (66           $('#msg').text( textStatus);67         }68       });69     });70   })71 </script>

View Code

  前台加密完成后就需要后台做解密处理,解密完成后需要使用MD5加密现有密码与数据库中用户密码进行比较验证,如果验证通过则需要写入cookie以便下次用户能自   动登录,由于cookie中我不希望用户名和密码都明码存储,我这里用到了AES加密的方式,自定义一个32位的加密密钥对cookie进行加密解密处理,后台c#代码如  下:

 1 [HttpPost] 2     public JsonResult UserLogin(string UserName, string Pwd, string Key, string RUrl) 3     { 4       string privateKey = Common.CacheGet(Key) as string; 5       if (!string.IsNullOrEmpty(privateKey)) 6       { 7         if (string.IsNullOrEmpty(UserName)) 8         { 9           return Json(new { result = false, message = "用户名为空" }, JsonRequestBehavior.AllowGet);10         }11         if (string.IsNullOrEmpty(Pwd))12         {13           return Json(new { result = false, message = "用户密码为空" }, JsonRequestBehavior.AllowGet);14         }15         string pwd = Common.DecryptRSA(Pwd, privateKey);//私钥解密16         string md5Pwd = Common.NoneEncrypt(Common.NoneEncrypt(Common.NoneEncrypt(pwd, 1), 1), 1);//将解密后的值md5加密3次17         AccountUnserInfo userInfo = bll.GetUserInfo(UserName.Trim(), md5Pwd);18         if (userInfo != null && userInfo.U_Id > 0)//用户信息存在19         {20           //用户名、密码放入cookie21           HttpCookie cookie = new HttpCookie("fw_izz");22           //AES加密Cookie23           cookie["u_name"] = AesEncryptHelper.EncryptAes(UserName);24           cookie["u_pwd"] = AesEncryptHelper.EncryptAes(pwd);25           cookie.Expires = DateTime.Now.AddDays(7);26           Response.Cookies.Add(cookie);27           if (!string.IsNullOrEmpty(RUrl))//接收隐藏域中的值28           {29             return Json(new { result = true, message = "成功", url = RUrl });30           }31           else32           {33             return Json(new { result = true, message = "成功", url = "/AccountDetail/Index" });34           }35         }36         else37         {38           return Json(new { result = false, message = "用户信息不存在", url = "/Account/Index" });39         }40       }41       else42       {43         return Json(new { result = false, message = "非法秘钥", url = "/Account/Index" });44       }45     }

View Code

  各种加密解密方法、Cache操作以及cookie操作代码如下: 

 1 public class Common 2   { 3     /// <summary> 4     /// 产生一组RSA公钥、私钥 5     /// </summary> 6     /// <returns></returns> 7     public static Dictionary<string, string> CreateRsaKeyPair() 8     { 9       var keyPair = new Dictionary<string, string>(); 10       var rsaProvider = new RSACryptoServiceProvider(1024); 11       RSAParameters parameter = rsaProvider.ExportParameters(true); 12       keyPair.Add("PUBLIC", BytesToHexString(parameter.Exponent) + "," + BytesToHexString(parameter.Modulus)); 13       keyPair.Add("PRIVATE", rsaProvider.Totrue)); 14       return keyPair; 15     } 16  17     /// <summary> 18     /// RSA解密字符串 19     /// </summary> 20     /// <param name="encryptData">密文</param> 21     /// <param name="privateKey">私钥</param> 22     /// <returns>明文</returns> 23     public static string DecryptRSA(string encryptData, string privateKey) 24     { 25       string decryptData = ""; 26       try 27       { 28         var provider = new RSACryptoServiceProvider(); 29         provider.From 30  31         byte[] result = provider.Decrypt(HexStringToBytes(encryptData), false); 32         ASCIIEncoding enc = new ASCIIEncoding(); 33         decryptData = enc.GetString(result); 34       } 35       catch (Exception e) 36       { 37         throw new Exception("RSA解密出错!", e); 38       } 39       return decryptData; 40     } 41  42     private static string BytesToHexString(byte[] input) 43     { 44       StringBuilder hexString = new StringBuilder(64); 45  46       for (int i = 0; i < input.Length; i++) 47       { 48         hexString.Append(String.Format("{0:X2}", input[i])); 49       } 50       return hexString.ToString(); 51     } 52  53     public static byte[] HexStringToBytes(string hex) 54     { 55       if (hex.Length == 0) 56       { 57         return new byte[] { 0 }; 58       } 59       if (hex.Length % 2 == 1) 60       { 61         hex = "0" + hex; 62       } 63       byte[] result = new byte[hex.Length / 2]; 64       for (int i = 0; i < hex.Length / 2; i++) 65       { 66         result[i] = byte.Parse(hex.Substring(2 * i, 2), System.Globalization.NumberStyles.AllowHexSpecifier); 67       } 68       return result; 69     } 70  71     private static ObjectCache Cache 72     { 73       get { return MemoryCache.Default; } 74     } 75     /// <summary> 76     /// 获取缓存 77     /// </summary> 78     /// <param name="key"></param> 79     /// <returns></returns> 80     public static object CacheGet(string key) 81     { 82       return Cache[key]; 83     } 84     /// <summary> 85     /// 设置缓存 86     /// </summary> 87     /// <param name="key"></param> 88     /// <param name="data"></param> 89     /// <param name="cacheTime"></param> 90     public static void CacheSet(string key, object data, int cacheTime) 91     { 92       CacheItemPolicy policy = new CacheItemPolicy(); 93       policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime); 94       Cache.Add(new CacheItem(key, data), policy); 95     } 96     /// <summary> 97     /// 判断缓存是否存在 98     /// </summary> 99     /// <param name="key"></param>100     /// <returns></returns>101     public static bool IsSet(string key)102     {103       return (Cache[key] != null);104     }105     /// <summary>106     /// 缓存失效107     /// </summary>108     /// <param name="key"></param>109     public static void CacheRemove(string key)110     {111       Cache.Remove(key);112     }113     /// <summary>114     /// 对字符串进行加密(不可逆)115     /// </summary>116     /// <param name="Password">要加密的字符串</param>117     /// <param name="Format">加密方式,0 is SHA1,1 is MD5</param>118     /// <returns></returns>119     public static string NoneEncrypt(string Password, int Format)120     {121       string strResult = "";122       switch (Format)123       {124         case 0:125           strResult = FormsAuthentication.HashPasswordForStoringInConfigFile(Password, "SHA1");126           break;127         case 1:128           strResult = FormsAuthentication.HashPasswordForStoringInConfigFile(Password, "MD5");129           break;130         default:131           strResult = Password;132           break;133       }134       return strResult;135     }136   }

View Code