ASP.NET MVC结合JavaScript登录、校验和加密
程序员文章站
2023-11-17 14:32:04
最近闲来无事给自己写了家庭财务收支管理系统,也就包含支出管理,收入管理和一些统计功能。
先说登录模块,因为涉及get和post请求,这些东西都是能被监控和抓取的所以就...
最近闲来无事给自己写了家庭财务收支管理系统,也就包含支出管理,收入管理和一些统计功能。
先说登录模块,因为涉及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; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。