原文地址
一飘痛、使用HTTP簡(jiǎn)單加密
對(duì)系統(tǒng)安全性要求比較高,那么需要選擇https協(xié)議來(lái)傳輸數(shù)據(jù)。當(dāng)然很多情況下一般的web網(wǎng)站,如果安全要求不是很高的話证九,用http協(xié)議就可以了。在這種情況下共虑,密碼的明文傳輸顯然是不合適的愧怜,因?yàn)槿绻?qǐng)求在傳輸過(guò)程中被截了,就可以直接拿明文密碼登錄網(wǎng)站了妈拌。
對(duì)于使用http協(xié)議的web前端的加密拥坛,只能防君子不能防小人。前端是完全暴露的,包括你的加密算法猜惋。 知道了加密算法丸氛,密碼都是可以破解的,只是時(shí)間問(wèn)題著摔。所以加密是為了增加破解的時(shí)間成本缓窜,如果破解需要花費(fèi)的時(shí)間讓人難以接受,這也就達(dá)到了目的梨撞。
而為了保證數(shù)據(jù)庫(kù)中存儲(chǔ)的密碼更安全雹洗,則需要在后端用多種單向(非對(duì)稱)加密手段混合進(jìn)行加密存儲(chǔ)香罐。前端加密后端又需要解密卧波,所以需要對(duì)稱加密算法,即前端使用 encrypted = encrypt(password+key)庇茫,后端使用 password = decrypt(encrypted +key) 港粱,前端只傳輸密碼與key加密后的字符串encrypted ,這樣即使請(qǐng)求被攔截了旦签,也知道了加密算法查坪,但是由于缺少key所以很難破解出明文密碼。所以這個(gè)key很關(guān)鍵宁炫。而這個(gè)key是由后端控制生成與銷毀的偿曙,用完即失效,所以即使可以模擬用加密后的密碼來(lái)發(fā)請(qǐng)求模擬登錄羔巢,但是key已經(jīng)失效了望忆,后端還是驗(yàn)證不過(guò)的。
注意竿秆,如果本地環(huán)境本就是不安全的启摄,key被知道了,那就瞬間就可以用解密算法破解出密碼了幽钢。這里只是假設(shè)傳輸?shù)倪^(guò)程中被截獲的情形歉备。所以前端加密是防不了小人的。如果真要防匪燕,可以將加密算法的js文件進(jìn)行壓縮加密蕾羊,不斷更新的手段來(lái)使js文件難以獲取,讓黑客難以獲取加密算法帽驯。變態(tài)的google就是這么干的肚豺,自己實(shí)現(xiàn)一個(gè)js虛擬機(jī),通過(guò)不斷更新加密混淆js文件讓加密算法難以獲取界拦。這樣黑客不知道加密算法就無(wú)法破解了吸申。
二、GOOGLE的JS加密算法庫(kù)crypto-js
去https://github.com/brix/crypto-js下載,develop和master下載稍有區(qū)別截碴。以MD5測(cè)試為例梳侨,只引入md5.js(未壓縮前為9K)會(huì)報(bào)錯(cuò),需要先引入core.js(未壓縮前為22K)日丹。而在master分支下載的crypto-js走哺,是所有加密算法合集(未壓縮前為188K),只需要引入這一個(gè)JS文件即可哲虾。
<head>
<script type="text/javascript" src="core.js"></script>
<script src="md5.js"></script>
</head>
<body>
</body>
<script>
var hash = CryptoJS.MD5("Message");
console.log("test:",hash.toString());
</script>
打印結(jié)果是test: 4c2a8fe7eaf24721cc7a9f0175115bd4
丙躏,與網(wǎng)站上對(duì)照結(jié)果一致。
1.再來(lái)測(cè)試一下AES加密
var encrypt = getAES("Message");
console.log("encrypt:",encrypt);
var decrypt = getDAes(encrypt);
console.log("decrypt:",decrypt);
function getAesString(data,key,iv){//加密
var key = CryptoJS.enc.Utf8.parse(key);
var iv = CryptoJS.enc.Utf8.parse(iv);
var encrypted =CryptoJS.AES.encrypt(data,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return encrypted.toString(); //返回的是base64格式的密文
}
function getDAesString(encrypted,key,iv){//解密
var key = CryptoJS.enc.Utf8.parse(key);
var iv = CryptoJS.enc.Utf8.parse(iv);
var decrypted =CryptoJS.AES.decrypt(encrypted,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
function getAES(data){ //加密
var key = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; //密鑰
var iv = '1234567812345678';
var encrypted =getAesString(data,key,iv); //密文
var encrypted1 =CryptoJS.enc.Utf8.parse(encrypted);
return encrypted;
}
function getDAes(data){//解密
var key = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; //密鑰
var iv = '1234567812345678';
var decryptedStr =getDAesString(data,key,iv);
return decryptedStr;
}
輸出結(jié)果
encrypt: GtV+06AIR7HQ8Bm4pRHdGw==
decrypt: Message
key和iv我們都可以更換束凑,但是需要保證的是加解密的key和vi保持一致
前端js
<script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/aes.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/md5.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/components/pad-zeropadding.js"></script>
<script>
var key_hash = CryptoJS.MD5("Message");
var key = CryptoJS.enc.Utf8.parse(key_hash);
var iv = CryptoJS.enc.Utf8.parse('1234567812345678');
var encrypted = CryptoJS.AES.encrypt("Message", key, { iv: iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.ZeroPadding});
document.write("encode:"+encrypted);
</script>
php代碼
<?php
$text = "Message";
$key = md5($text); //key的長(zhǎng)度必須16晒旅,32位,這里直接MD5一個(gè)長(zhǎng)度為32位的key
$iv='1234567812345678';
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv);
$decode = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $crypttext, MCRYPT_MODE_CBC, $iv);
echo base64_encode($crypttext);
echo "<br/>";
echo $decode;
echo "<br/>";
?>
3.實(shí)戰(zhàn)
- 參考
關(guān)于CryptoJS中md5加密以及aes加密的隨筆
為什么 CryptoJS DES 加密的結(jié)果和 Java DES 不一樣?
用的CBC模式,AES-128bit, Pkcs7補(bǔ)碼方式(后臺(tái)有可能是PKCS5Padding汪诉,是一樣的)废恋,一開(kāi)始后臺(tái)設(shè)定的key是10位,他們都可以加密和解密扒寄,但是我用了就是不行鱼鼓,我覺(jué)得肯定是我沒(méi)有處理好,但是最終實(shí)在沒(méi)辦法大家都改成16位该编,就對(duì)了迄本,可以跟后臺(tái)對(duì)上了