paip.提升安全---绝大多数网站的登录高危漏洞解决方案
作者Attilax , 1466519819@qq.com
WEB登录密码明文传输的严重性
今天,几乎所有的网站都有登录注册模块,登录就要输入用户名和登录密码,并且,用户名和登录密码都是明文传输的,这样就有可能在中途被别人拦截,尤其是在网吧等场合。
JS实现 RSA非对称加密算法
所以,很多安全要求较高的网站都不会明文传输密码,它们会使用https来确保传输过程的安全,https是用证书来实现的,证书来自于证书颁发机构,当然了,你也可以自己造一张证书,但这样别人访问你的网站的时候还是会遇到麻烦,因为你自己造的证书不在用户浏览器的信任范围之内,你还得在用户浏览器上安装你的证书,来让用户浏览器相信你的网站,很多用户并不知道如何操作,就算会操作,也能也不乐意干;另一种选择是你向权威证书颁发机构申请一张证书,但这样有一定的门槛,还需要付费,也不是我们乐意干的事。
所以使用JS来实现RSA加密是个很好的方法..我的网站是ASP。NET的.. 真正的难点在于用javascript实现一个和.net的RSA兼容的算法
加解密及传输流程
后台产生一对公钥私钥
传给WEB页面
登录/注册的时候,使用JS加密
后台解码.
后台产生一对公钥下发给WEB页
protected void Page_Load(object sender, EventArgse)
{
pwdEncode pe= new pwdEncode();
string[] ret=pe.PublicKey();
strPublicKeyExponent=ret[0];
strPublicKeyModulus=ret[1];
}
protected string strPublicKeyExponent="";
protected string strPublicKeyModulus="";
WEB页JS调用公钥进行加密提交
//两个加密文本框,加密后的密码保存在这里..如果是登录页面,只需要一个就可以了
<input name="encrypted_pwd" type="hidden" id="encrypted_pwd" />
<input name="encrypted_pwd2" type="hidden" id="encrypted_pwd2" />
//调用相关JS
<SCRIPT type=text/javascript src="/index_files/Account.js"></SCRIPT>
<script src="/Scripts/jQuery.md5.js" type="text/javascript" ></script>
<script src="/Scripts/BigInt.js" type="text/javascript"></script>
<script src="/Scripts/RSA.js" type="text/javascript"></script>
<script src="/Scripts/Barrett.js" type="text/javascript"></script>
<script>
//从后台得到公钥
var strPublicKeyExponent="<%= strPublicKeyExponent%>";
var strPublicKeyModulus="<%=strPublicKeyModulus%>";
//加密函数
function cmdEncrypt() {
setMaxDigits(129);
var key = new RSAKeyPair(strPublicKeyExponent, "", strPublicKeyModulus);
var pwdMD5Twice = $("#SignIn_Pword").attr("value");
var pwdRtn = encryptedString(key, pwdMD5Twice);
$("#encrypted_pwd").attr("value", pwdRtn);
//注意:需要清空原密码框
$("#SignIn_Pword").attr("value","");
}
//登录按扭事件
function login_click()
{
cmdEncrypt() ;
return true;
}
//登录按扭事件注册
$('#SignIn_SignInClt').click=login_click;
$('#SignIn_SignInClt').click(function(){
login_click();
});
后台校验密码不能为空
因为使用了加密方式,所以原来的校验需要去掉,使用新的校验方式
loginCheckor lc= new loginCheckor();
lc.check(Account, Request["encrypted_pwd"]);
public bool check(string uname,string pwd)
{
if (uname=="")
{
throw new SystemException("帐¨º号?未¡ä输º?入¨?");
}
// if(uname==null|| uname.Equals(""))
if (pwd== null ||pwd.Equals(""))
throw new Exception("密¨¹码?不?能¨¹为a空?");
//
//TODO: 在¨²此ä?处ä|添¬¨ª加¨®构1造¨¬函¡¥数ºy逻?辑-
//
return true;
}
如果是注册页面
//ati L921 am
pwdEncode pe= new pwdEncode();
pe.checkEmpty(Request["encrypted_pwd"], Request["encrypted_pwd2"]);
string pwd=pe.getPwd(Request["encrypted_pwd"]);
string Pword2=pe.getPwd(Request["encrypted_pwd2"]);
pe.check(pwd, Pword2); //检测两个密码是否相同
//不能直接检测参数,因为公钥加密后的两个参数不同,需要解密后进行比较
解密密码
-------登录后台
pwdEncode pe= new pwdEncode();
Pword=pe.getPwd(Request["encrypted_pwd"]);
密码编码器pwdEncode大部分原码
//这里主要使用session来保存RSA加密器和私钥
//发送公钥
public string[] sendPublicKey()
{
RSACryptoServiceProvider rsa;
if (HttpContext.Current.Session["rsa"] != null)
rsa= (RSACryptoServiceProvider)HttpContext.Current.Session["rsa"];
else
rsa= new RSACryptoServiceProvider();
//if (string.Compare(Request.RequestType, "get", true) == 0)
{
//将?私?钥?存ä?Session中D
HttpContext.Current.Session["private_key"] =rsa.ToXmlString(true);
HttpContext.Current.Session["rsa"] =rsa;
}
//把ã?公?钥?适º¨º当Ì¡À转Áa换?,ê?准Á?备À?发¤¡é往ª¨´客¨ª户¡ì端?
pwdEncode pe= new pwdEncode();
RSAParameters parameter=rsa.ExportParameters(true);
string strPublicKeyExponent=pe.BytesToHexString(parameter.Exponent);
string strPublicKeyModulus=pe.BytesToHexString(parameter.Modulus);
string[] r= new string[2];
r[0] =strPublicKeyExponent;
r[1] =strPublicKeyModulus;
return r;
}
//解密函数
private static string getDecodePwd(string pwd)
{
RSACryptoServiceProvider rsa;
rsa= (RSACryptoServiceProvider)HttpContext.Current.Session["rsa"];
pwdEncode pe= new pwdEncode();
// RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
string strPwdToDecrypt=pwd;
rsa.FromXmlString((string)HttpContext.Current.Session["private_key"]);
byte[] result=rsa.Decrypt(pwdEncode.HexStringToBytes(strPwdToDecrypt), false);
System.Text.ASCIIEncodingenc= new ASCIIEncoding();
string strPwdMD5=enc.GetString(result);
return strPwdMD5;
}
参考:
用RSA加密实现Web登录密码加密传输 - guogangj - 博客园