對代碼進(jìn)行重構(gòu)逊脯,頁面跳轉(zhuǎn)的時候總是提示參數(shù)錯誤优质,仔細(xì)檢查了好幾遍,確定就是那幾個參數(shù)军洼,最后找出原始頁面對比巩螃,原來必須要加密傳輸才可以。
事實(shí)上匕争,在平時的項(xiàng)目開發(fā)中避乏,經(jīng)常要考慮到對數(shù)據(jù)進(jìn)行加密傳輸?shù)膯栴}。數(shù)據(jù)在傳輸?shù)倪^程中甘桑,如果使用原始數(shù)據(jù)拍皮,就可能會出現(xiàn)被監(jiān)聽歹叮、被截獲、被篡改的情況春缕,會產(chǎn)生非常大的安全隱患盗胀。因此開發(fā)人員需要在客戶端對傳輸數(shù)據(jù)進(jìn)行加密艘蹋,然后在服務(wù)器端進(jìn)行解密锄贼!
看了看原來的代碼,確定了他們用的是AES
對稱加密算法.
AES
加密算法分為3種女阀,分別是AES-128
宅荤,AES-192
,AES-256
浸策。AES
加密的實(shí)現(xiàn)主要由4種操作組成冯键,分別是字節(jié)代替、行位移庸汗、列混淆惫确、輪密鑰加。另外還需要對原始密鑰進(jìn)行擴(kuò)展蚯舱,這種加密方式計算量小改化、速度塊,適合對大量數(shù)據(jù)進(jìn)行加密的場景枉昏。
AES
加密整套加密系統(tǒng)包括以下幾個部分:
- 明文P
沒有經(jīng)過加密的數(shù)據(jù)陈肛。
- 密鑰K
用來加密明文的密碼,在對稱加密算法中兄裂,加密與解密的密鑰是相同的句旱。密鑰為接收方與發(fā)送方協(xié)商產(chǎn)生,但不可以直接在網(wǎng)絡(luò)上傳輸晰奖,否則會導(dǎo)致密鑰泄漏谈撒,通常是通過非對稱加密算法加密密鑰,然后再通過網(wǎng)絡(luò)傳輸給對方匾南,或者直接面對面商量密鑰港华。密鑰是絕對不可以泄漏的,否則會被攻擊者還原密文午衰,竊取機(jī)密數(shù)據(jù)立宜。
- 加密函數(shù)
設(shè)AES加密函數(shù)為E,則 C = E(K, P),其中P為明文臊岸,K為密鑰橙数,C為密文。也就是說帅戒,把明文P和密鑰K作為加密函數(shù)的參數(shù)輸入灯帮,則加密函數(shù)E會輸出密文C崖技。
- 密文C
經(jīng)加密函數(shù)處理后的數(shù)據(jù)
- 解密函數(shù)
設(shè)AES解密函數(shù)為D,則 P = D(K, C),其中C為密文钟哥,K為密鑰迎献,P為明文。也就是說腻贰,把密文C和密鑰K作為解密函數(shù)的參數(shù)輸入吁恍,則解密函數(shù)會輸出明文P。
AES
加密的五個必須了解的關(guān)鍵點(diǎn):
要理解AES的加密流程播演,會涉及到AES加密的五個關(guān)鍵詞冀瓦,分別是:分組密碼體制、Padding写烤、密鑰翼闽、初始向量IV和四種加密模式
- 分組密碼體制:
將明文切成一段一段的來加密,然后再把一段一段的密文拼起來形成最終密文的加密方式洲炊。
AES采用分組密碼體制感局,即AES加密會首先把明文切成一段一段的,而且每段數(shù)據(jù)的長度要求必須是128位16個字節(jié)暂衡,如果最后一段不夠16個字節(jié)了询微,就需要用Padding來把這段數(shù)據(jù)填滿16個字節(jié),然后分別對每段數(shù)據(jù)進(jìn)行加密古徒,最后再把每段加密數(shù)據(jù)拼起來形成最終的密文拓提。
- Padding:
把不滿16個字節(jié)的分組數(shù)據(jù)填滿16個字節(jié)。
它有三種模式PKCS5隧膘、PKCS7和NOPADDING代态。
- PKCS5是指分組數(shù)據(jù)缺少幾個字節(jié),就在數(shù)據(jù)的末尾填充幾個字節(jié)的幾疹吃,比如缺少5個字節(jié)蹦疑,就在末尾填充5個字節(jié)的5。
- PKCS7是指分組數(shù)據(jù)缺少幾個字節(jié)萨驶,就在數(shù)據(jù)的末尾填充幾個字節(jié)的0歉摧,比如缺少7個字節(jié),就在末尾填充7個字節(jié)的0腔呜。
- NoPadding是指不需要填充叁温,也就是說數(shù)據(jù)的發(fā)送方肯定會保證最后一段數(shù)據(jù)也正好是16個字節(jié)。
如果在PKCS5模式下核畴,最后一段數(shù)據(jù)的內(nèi)容剛好就是16個16怎么辦膝但?那解密端就不知道這一段數(shù)據(jù)到底是有效數(shù)據(jù)還是填充數(shù)據(jù)了,因此對于這種情況谤草,PKCS5模式會自動幫我們在最后一段數(shù)據(jù)后再添加16個字節(jié)的數(shù)據(jù)跟束,而且填充數(shù)據(jù)也是16個16莺奸,這樣解密段就能知道誰是有效數(shù)據(jù)誰是填充數(shù)據(jù)了。PKCS7最后一段數(shù)據(jù)的內(nèi)容是16個0冀宴,也是同樣的道理灭贷。解密端需要使用和加密端同樣的Padding模式,才能準(zhǔn)確的識別有效數(shù)據(jù)和填充數(shù)據(jù)略贮。我們開發(fā)通常采用PKCS7 Padding模式甚疟。
- 初始向量IV:
初始向量IV的作用是使加密更加安全可靠,我們使用AES加密時需要主動提供初始向量刨肃,而且只需要提供一個初始向量就夠了古拴,后面每段數(shù)據(jù)的加密向量都是前面一段的密文箩帚。初始向量IV的長度規(guī)定為128位16個字節(jié)真友,初始向量的來源為隨機(jī)生成。至于為什么初始向量能使加密更安全可靠紧帕,會在下面的加密模式中提到盔然。
- 密鑰:
AES要求密鑰的長度可以是128位16個字節(jié)、192位或者256位是嗜,位數(shù)越高愈案,加密強(qiáng)度自然越大,但是加密的效率自然會低一些鹅搪,因此要做好衡量站绪。我們開發(fā)通常采用128位16個字節(jié)的密鑰,我們使用AES加密時需要主動提供密鑰丽柿,而且只需要提供一個密鑰就夠了恢准,每段數(shù)據(jù)加密使用的都是這一個密鑰,密鑰來源為隨機(jī)生成甫题。
- 四種加密模式:
AES一共有四種加密模式馁筐,分別是ECB(電子密碼本模式)、CBC(密碼分組鏈接模式)坠非、CFB敏沉、OFB,我們一般使用的是CBC模式炎码。四種模式中除了ECB相對不安全之外盟迟,其它三種模式的區(qū)別并沒有那么大。
加密解密流程如下:
發(fā)送方使用密鑰K
將明文數(shù)據(jù)P
通過AES
加密函數(shù)加密成密文C
潦闲,然后發(fā)送出去攒菠,接收方收到密文C
后,使用同一個密鑰文件K
將密文解密成明文讀取矫钓。
以最常見的AES-128
為例,加密流程如下
加密過程:首先明文進(jìn)行1次輪密鑰加要尔;然后循環(huán)9輪字節(jié)代替舍杜、行位移、列混淆赵辕、輪密鑰加既绩;注意第10輪沒有列混淆。
解密過程:解密過程與加密過程相反还惠,這也是對稱加密算法的特點(diǎn)饲握。首先密文進(jìn)行1次輪密鑰加;然后循環(huán)9輪逆向行位移蚕键、逆向字節(jié)代替救欧、輪密鑰加、逆向列混淆锣光;注意第10輪沒有逆向列混淆笆怠。
AES-192
和AES-256
與AES-128
相似,只是密鑰長度和加密輪數(shù)不一樣誊爹。AES
作為對稱加密算法蹬刷,加密和解密用相同密鑰;加密速度快频丘,適合用于經(jīng)常發(fā)送數(shù)據(jù)的場合办成。
更加詳細(xì)的算法過程可移步AES加密算法(帶示例)
了解了這些原理其實(shí)就簡單了,網(wǎng)上有很多封裝好的加密算法搂漠,直接引用并稍加修改即可迂卢,具體代碼實(shí)現(xiàn)如下:
1. 引入crypto-js
npm install crypto-js --save
2. 在src
的utils
文件夾下新建一個文件:encrypt.js
const CryptoJS = require('crypto-js'); //引用AES源碼js
//加密方法
var encryptKey = '**********'; //秘鑰
function argEncryptByDES(message) {
var keyHex = CryptoJS.enc.Utf8.parse(encryptKey);
var ciphertext = CryptoJS.enc.Utf8.parse(message);
var encrypted = CryptoJS.DES.encrypt(ciphertext, keyHex, {
mode:CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
// 單個參數(shù)des解密
function argDecryptByDES(message) {
var keyHex = CryptoJS.enc.Utf8.parse(encryptKey);
var decrypted = CryptoJS.DES.decrypt(message, keyHex, {
mode:CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
export default {
argEncryptByDES, argDecryptByDES
}
3.在傳參頁面引入加密解密文件
import encrypt from "../../utils/encrypt"
4.最后,在傳參時記得給參數(shù)加密
encrypt.argEncryptByDES(參數(shù))