ASP.NET MVC结合JavaScript登录、校验和加密
最近闲来无事给自己写了家庭财务收支管理系统,也就包含支出管理,收入管理和一些统计功能。
先说登录模块,因为涉及GET和POST请求,这些东西都是能被监控和抓取的所以就考虑这使用RSA加密解密方式传输用户名和密码参数,页面JS如下:
/*需要引入三个JS文件,BigInt.js、RSA.js和Barrett.js,用到cookie则需要引入jquery.cookie.js文件*/
//与后台交互获取公钥
functiongetPublicKey(){
varpubKey='';
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');
}
returnpubKey;
}
//公钥加密用户密码Pwd为RSA加密后参数
functionrsaEncrypt(pwd){
varpublicKey=getPublicKey();
setMaxDigits(129);
varrsaKey=newRSAKeyPair(publicKey.split(",")[0],"",publicKey.split(",")[1]);
varpwdRtn=encryptedString(rsaKey,pwd);
returnpwdRtn+","+publicKey.split(",")[2];
}
//POST登录请求,参数
<scripttype="text/javascript">
$(function(){
$('#btnSubmit').live('click',function(){
varuName=$('#u').val();
varpwd=$('#p').val();
if(uName==''){
alert('用户名不能为空');
return;
}
if(pwd==''){
alert('用户密码不能为空');
return;
}
varenPwd=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;
returnfalse;
}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]
publicJsonResultUserLogin(stringUserName,stringPwd,stringKey,stringRUrl)
{
stringprivateKey=Common.CacheGet(Key)asstring;
if(!string.IsNullOrEmpty(privateKey))
{
if(string.IsNullOrEmpty(UserName))
{
returnJson(new{result=false,message="用户名为空"},JsonRequestBehavior.AllowGet);
}
if(string.IsNullOrEmpty(Pwd))
{
returnJson(new{result=false,message="用户密码为空"},JsonRequestBehavior.AllowGet);
}
stringpwd=Common.DecryptRSA(Pwd,privateKey);//私钥解密
stringmd5Pwd=Common.NoneEncrypt(Common.NoneEncrypt(Common.NoneEncrypt(pwd,1),1),1);//将解密后的值md5加密3次
AccountUnserInfouserInfo=bll.GetUserInfo(UserName.Trim(),md5Pwd);
if(userInfo!=null&&userInfo.U_Id>0)//用户信息存在
{
//用户名、密码放入cookie
HttpCookiecookie=newHttpCookie("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))//接收隐藏域中的值
{
returnJson(new{result=true,message="成功",url=RUrl});
}
else
{
returnJson(new{result=true,message="成功",url="/AccountDetail/Index"});
}
}
else
{
returnJson(new{result=false,message="用户信息不存在",url="/Account/Index"});
}
}
else
{
returnJson(new{result=false,message="非法秘钥",url="/Account/Index"});
}
}
各种加密解密方法、Cache操作以及cookie操作代码如下:
publicclassCommon
{
///<summary>
///产生一组RSA公钥、私钥
///</summary>
///<returns></returns>
publicstaticDictionary<string,string>CreateRsaKeyPair()
{
varkeyPair=newDictionary<string,string>();
varrsaProvider=newRSACryptoServiceProvider(1024);
RSAParametersparameter=rsaProvider.ExportParameters(true);
keyPair.Add("PUBLIC",BytesToHexString(parameter.Exponent)+","+BytesToHexString(parameter.Modulus));
keyPair.Add("PRIVATE",rsaProvider.ToXmlString(true));
returnkeyPair;
}
///<summary>
///RSA解密字符串
///</summary>
///<paramname="encryptData">密文</param>
///<paramname="privateKey">私钥</param>
///<returns>明文</returns>
publicstaticstringDecryptRSA(stringencryptData,stringprivateKey)
{
stringdecryptData="";
try
{
varprovider=newRSACryptoServiceProvider();
provider.FromXmlString(privateKey);
byte[]result=provider.Decrypt(HexStringToBytes(encryptData),false);
ASCIIEncodingenc=newASCIIEncoding();
decryptData=enc.GetString(result);
}
catch(Exceptione)
{
thrownewException("RSA解密出错!",e);
}
returndecryptData;
}
privatestaticstringBytesToHexString(byte[]input)
{
StringBuilderhexString=newStringBuilder(64);
for(inti=0;i<input.Length;i++)
{
hexString.Append(String.Format("{0:X2}",input[i]));
}
returnhexString.ToString();
}
publicstaticbyte[]HexStringToBytes(stringhex)
{
if(hex.Length==0)
{
returnnewbyte[]{0};
}
if(hex.Length%2==1)
{
hex="0"+hex;
}
byte[]result=newbyte[hex.Length/2];
for(inti=0;i<hex.Length/2;i++)
{
result[i]=byte.Parse(hex.Substring(2*i,2),System.Globalization.NumberStyles.AllowHexSpecifier);
}
returnresult;
}
privatestaticObjectCacheCache
{
get{returnMemoryCache.Default;}
}
///<summary>
///获取缓存
///</summary>
///<paramname="key"></param>
///<returns></returns>
publicstaticobjectCacheGet(stringkey)
{
returnCache[key];
}
///<summary>
///设置缓存
///</summary>
///<paramname="key"></param>
///<paramname="data"></param>
///<paramname="cacheTime"></param>
publicstaticvoidCacheSet(stringkey,objectdata,intcacheTime)
{
CacheItemPolicypolicy=newCacheItemPolicy();
policy.AbsoluteExpiration=DateTime.Now+TimeSpan.FromMinutes(cacheTime);
Cache.Add(newCacheItem(key,data),policy);
}
///<summary>
///判断缓存是否存在
///</summary>
///<paramname="key"></param>
///<returns></returns>
publicstaticboolIsSet(stringkey)
{
return(Cache[key]!=null);
}
///<summary>
///缓存失效
///</summary>
///<paramname="key"></param>
publicstaticvoidCacheRemove(stringkey)
{
Cache.Remove(key);
}
///<summary>
///对字符串进行加密(不可逆)
///</summary>
///<paramname="Password">要加密的字符串</param>
///<paramname="Format">加密方式,0isSHA1,1isMD5</param>
///<returns></returns>
publicstaticstringNoneEncrypt(stringPassword,intFormat)
{
stringstrResult="";
switch(Format)
{
case0:
strResult=FormsAuthentication.HashPasswordForStoringInConfigFile(Password,"SHA1");
break;
case1:
strResult=FormsAuthentication.HashPasswordForStoringInConfigFile(Password,"MD5");
break;
default:
strResult=Password;
break;
}
returnstrResult;
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。