最近闲来无事给自己写了家庭财务收支管理系统,也就包含支出管理,收入管理和一些统计功能。
先说登录模块,因为涉及GET和POST请求,这些东西都是能被监控和抓取的所以就考虑这使用RSA加密解密方式传输用户名和密码参数,页面JS如下:
/*需要引入三个JS文件,BigInt.js、RSA.js和Barrett.js,用到cookie则需要引入jquery.cookie.js文件*/ //与后台交互获取公钥 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加密后参数 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登录请求,参数 <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>
前台加密完成后就需要后台做解密处理,解密完成后需要使用MD5加密现有密码与数据库中用户密码进行比较验证,如果验证通过则需要写入cookie以便下次用户能自 动登录,由于cookie中我不希望用户名和密码都明码存储,我这里用到了AES加密的方式,自定义一个32位的加密密钥对cookie进行加密解密处理,后台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> /// 产生一组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解密出错!\", 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> /// 设置缓存 /// </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> /// 对字符串进行加密(不可逆) /// </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; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持phpstudy。
本文地址:https://www.stayed.cn/item/3234
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我