zoukankan      html  css  js  c++  java
  • 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 (XMLHttpRequest, textStatus, errorThrown) {
    66                     $('#msg').text(XMLHttpRequest.status + '||' + XMLHttpRequest.readyState + '||' + 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                     //用户名、密码放入cookie
    21                     HttpCookie cookie = new HttpCookie("fw_izz");
    22                     //AES加密Cookie
    23                     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                     else
    32                     {
    33                         return Json(new { result = true, message = "成功", url = "/AccountDetail/Index" });
    34                     }
    35                 }
    36                 else
    37                 {
    38                     return Json(new { result = false, message = "用户信息不存在", url = "/Account/Index" });
    39                 }
    40             }
    41             else
    42             {
    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.ToXmlString(true));
     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.FromXmlString(privateKey);
     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
  • 相关阅读:
    bom案例2-弹出层
    bom案例1-div拖拽
    bom-scroll
    bom-client
    bom-offset
    9. 阻塞队列
    8. 读写锁
    7. CountDownLatch、CyclicBarrier、Semaphore
    6. Callable
    5. 集合不安全
  • 原文地址:https://www.cnblogs.com/IclearByte/p/5771817.html
Copyright © 2011-2022 走看看