paip.提升安全---絕大多數網站的登入高危漏洞解決方案
作者Attilax , [email protected]
WEB登入密碼明文傳輸的嚴重性... 1
JS實作 RSA非對稱加密算法... 1
加解密及傳輸流程... 1
背景産生一對公鑰下發給WEB頁... 2
WEB頁JS調用公鑰進行加密送出... 2
背景校驗密碼不能為空... 3
解密密碼... 4
密碼編碼器pwdEncode大部分原碼... 4
參考:6
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 - 部落格園