芙姬情感网
您的当前位置:首页ASP.NET MVC结合JavaScript登录、校验和加密

ASP.NET MVC结合JavaScript登录、校验和加密

来源:芙姬情感网


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

先说登录模块,因为涉及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();

 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;
 }
 }
显示全文