程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> ASP.NET基礎 >> ASP.NET MVC結合JavaScript登錄、校驗和加密

ASP.NET MVC結合JavaScript登錄、校驗和加密

編輯:ASP.NET基礎

最近閒來無事給自己寫了家庭財務收支管理系統,也就包含支出管理,收入管理和一些統計功能。

先說登錄模塊,因為涉及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;
    }
  }

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved