最近閑來無事給自己寫了家庭財(cái)務(wù)收支管理系統(tǒng),也就包含支出管理,收入管理和一些統(tǒng)計(jì)功能。
先說登錄模塊,因?yàn)樯婕癎ET和POST請(qǐng)求,這些東西都是能被監(jiān)控和抓取的所以就考慮這使用RSA加密解密方式傳輸用戶名和密碼參數(shù),頁面JS如下:
/*需要引入三個(gè)JS文件,BigInt.js、RSA.js和Barrett.js,用到cookie則需要引入jquery.cookie.js文件*/
//與后臺(tái)交互獲取公鑰
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加密后參數(shù)
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登錄請(qǐng)求,參數(shù)
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>
前臺(tái)加密完成后就需要后臺(tái)做解密處理,解密完成后需要使用MD5加密現(xiàn)有密碼與數(shù)據(jù)庫中用戶密碼進(jìn)行比較驗(yàn)證,如果驗(yàn)證通過則需要寫入cookie以便下次用戶能自 動(dòng)登錄,由于cookie中我不希望用戶名和密碼都明碼存儲(chǔ),我這里用到了AES加密的方式,自定義一個(gè)32位的加密密鑰對(duì)cookie進(jìn)行加密解密處理,后臺(tái)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>
/// 產(chǎn)生一組RSA公鑰、私鑰
/// /summary>
/// returns>/returns>
public static Dictionarystring, string> CreateRsaKeyPair()
{
var keyPair = new Dictionarystring, 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解密出錯(cuò)!", 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>
/// 設(shè)置緩存
/// /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>
/// 對(duì)字符串進(jìn)行加密(不可逆)
/// /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;
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:- js實(shí)現(xiàn)登錄注冊(cè)框手機(jī)號(hào)和驗(yàn)證碼校驗(yàn)(前端部分)
- JavaScript 完成注冊(cè)頁面表單校驗(yàn)的實(shí)例
- JavaScript注冊(cè)時(shí)密碼強(qiáng)度校驗(yàn)代碼
- js簡(jiǎn)單實(shí)現(xiàn)用戶注冊(cè)信息的校驗(yàn)代碼
- JS校驗(yàn)與最終登陸界面功能完整示例
- 詳解AngularJs HTTP響應(yīng)攔截器實(shí)現(xiàn)登陸、權(quán)限校驗(yàn)
- Angular.js與node.js項(xiàng)目里用cookie校驗(yàn)賬戶登錄詳解
- jsp登陸校驗(yàn)演示 servlet、login、success
- 攔截JSP頁面,校驗(yàn)是否已登錄詳解及實(shí)現(xiàn)代碼
- javascript使用正則表達(dá)式實(shí)現(xiàn)注冊(cè)登入校驗(yàn)