在數據傳輸過程當中,可能存在數據被竊取的安全隱患(主要http)。 對於安全需求較高的項目而言,加密是保證數據安全的最直接的方式。前端
常見加密方式分爲如下兩類:node
Tips:ios
MD五、SHA256等通常稱爲數據摘要算法(採用哈希算法),即將數據塊映射爲定長的摘要信息,過程是單向的(沒法反推原數據),通常用於數據驗籤(校驗數據是否完整或校驗數據是否被篡改)。算法
以中後臺管理項目爲例:數據庫
需完善點:npm
設想: 鑑於AES較高的性能及RSA公私鑰方式的易用性,可否結合這二者的優勢實現對數據安全的保障?element-ui
如下是構思的業務流程:axios
這裏結合Vue實現 Tip:後端
// 預登陸 獲取後臺公鑰
preLogin (formName) {
// 校驗 預登陸表單(此處爲element-ui,其餘ui框架相似)
this.$refs[formName].validate(async (valid) => {
if (valid) {
const res = await adminPreLogin({
name: this.form.username, // 用戶名
verifyCode: this.form.verificationCode, // 驗證碼(經過get請求+tag參數獲取驗證碼圖片)
tag: this.uuid // 獲取驗證碼時的tag(可以使用uuid或時間戳+隨機數等方式生成)
})
if (res.data.res === 0) {
// 正式登陸 傳入後臺返回的公鑰及後臺生成這次預登陸的preSessionId
// 正式登陸後,後臺可根據此preSessionId查找對應的RSA私鑰進行解密
// 同一時間內可能存在多人同時登陸帳號(引入preSessionId解決)
this.login(res.data.publicKey, res.data.preSessionId)
} else {
// 預登陸失敗,則刷新驗證碼,重置驗證碼輸入框
this.uuid = uuidv4()
this.$set(this.form, 'verificationCode', '')
}
}
})
}
複製代碼
async login (publicKey, preSessionId) {
// 隨機生成 構成key iv的字符串(這裏都採用AES密鑰長度16位)
let keyString = randomGenerate(16) // 這裏使用工具類隨機生成(詳細實現見下文)
let ivString = randomGenerate(16)
// 生成AES 密鑰和向量
let key = CryptoJS.enc.Utf8.parse(keyString) // AES密鑰
let iv = CryptoJS.enc.Utf8.parse(ivString) // AES向量
// RSA公鑰加密
let pubKey = new NodeRSA(publicKey)
pubKey.setOptions({ encryptionScheme: 'pkcs1' }) // 設置填充方式,前、後端保持統一便可
// 這裏拆分出
let pwd = CryptoJS.AES.encrypt(
this.form.password, // 加密原文
key, // AES密鑰
{
iv: iv, // AES向量
mode: CryptoJS.mode.CBC, // 指定CBC模式
padding: CryptoJS.pad.Pkcs7 // 指定pkcs7填充模式
})
// 發送正式登陸請求
const res = await adminLogin({
name: this.form.username,
password: pwd,
authKey: pubKey.encrypt(keyString, 'base64'), // 加密後base64編碼
authIv: pubKey.encrypt(ivString, 'base64'),
preSessionId: preSessionId // 預登陸返回的preSessionId
})
if (res.data.res === 0) {
// 驗證成功後,可存儲AES密鑰和向量,後續請求關鍵信息使用AES加密後上傳便可
sessionStorage.setItem('aesKey', keyString)
sessionStorage.setItem('aesIv', ivString)
this.$router.push({ name: 'xxx-home' }) // 進入管理主頁面
// 還能夠存儲token、session等信息,並提示用戶登陸成功 這裏不作展現
} else {
// 正式登陸失敗,則刷新驗證碼,重置驗證碼輸入框
this.uuid = uuidv4()
this.$set(this.form, 'verificationCode', '')
}
}
複製代碼
// 生成隨機字符串
function randomGenerate (length) {
const chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
if (!Number.isInteger(length) || length <= 0) { // 合法性校驗
console.error('請檢查輸入隨機字符串長度是否爲正整數!')
return 'Error'
}
let randomString = ''
for (let i = 0; i < length; i++) {
randomString += chars[Math.floor(Math.random() * chars.length)]
}
return randomString
}
export { randomGenerate }
複製代碼
理解AES + RSA的結合加密思路後,實現方式可根據具體狀況修改。 結合兩種加密方式使用,能夠知足大多數的使用場景,發揮出各自的優勢。安全
————加密定義及分類摘自百度百科
歡迎你們積極討論,共同進步。 個人簡書