一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情。
前端如何转码加密后缓存?localStorage 转码加密存储解密获取
需求场景描述
web前端在storage中存储一些东西,是常见现象,包括存在localStorage或sessionStorage等storage中。如果直接存明文,别人一个F12就能查看存储的信息,虽然这些信息通常是不够敏感的,但这多多少少会有点不符合程序员的神秘强大的气质吧(嗯,就是有点low的意思)。如果加密转码成密文再缓存到storage中,相信从安全脱敏到外观都会好一些。
那么,在前端,我们可以用什么方法做到,先加密转码成密文信息,需要时再解密成明文,而且中间能够保证信息的完整性和一致性呢?这就是我们的需求了,下面分享实践后的解决方案。
先看下加密前后效果图对比
实现思路分析
以加密转码存储到localStorage,又从localStorage中取用为例子。
1.加密转码后存储。
第一步,先使用JSON.stringify()转换数据为string,
第二部,再使用encodeURIComponent()函数,编码数据,
第三步,使用window.btoa(),对数据进行二次编码,
第四步,存储到localStorage中。
最后,加密转码函数如下:
/**
* 加密编码数据 使用 btoa 结合 encodeURIComponent 加密编码数据
* @param data 需要加密编码的数据
*/
export function btoaEncode (data) {
if (!data) {
console.error('加密转码数据不能为空')
return ''
}
try {
data = window.btoa(encodeURIComponent(JSON.stringify(data)))
} catch (e) {
console.error('加密转码异常', e)
}
return data
}
复制代码
2.解密转码后取用。
第一步,从通过localStorage.getItem(),从localStorage取出数据,
第二步,使用window.atob()对数据解码,
第三步,再使用decodeURIComponent()对数据进行二次解码,
第四步,使用JSON.parse(),将string数据恢复为原数据,
解密转码函数如下:
/**
* 解密解码数据 使用 atob 结合 decodeURIComponent 解密解码数据
* @param data 需要解密转码的数据
*/
export function atobDecode (data) {
if (!data) {
console.error('解密解码数据不能为空')
return ''
}
try {
data = JSON.parse(decodeURIComponent(window.atob(data)))
} catch (e) {
console.error('解密解码异常', e)
}
return data
}
复制代码
相关技术点说明:
为什么要经历这么多步骤?每一步都是有意义的,比如btoa是使用base-64编码,编码成ASCII字符串,但是btoa的编码范围是Latin1,即是说不能对中文进行编码。所以得先使用encodeURIComponent()编码,而在此之前先需要使用JSON.stringify()将数据转换为JSON字符串,这一步是因为encodeURIComponent()只能对字符串进行编码。反之的解码规则是根据编码规则来进行的。
使用jsencrypt进行RSA 非对称加密也会遇到相应的问题,而且不能太长,会遇到Message too long for RSA,所以jsencrypt不靠谱。
关键技术介绍
1.btoa()和atob()
btoa() 和 atob() 是window对象的两个函数。
btoa(),是binary to ascii,用于将binary的数据用ascii码表示,即Base64的编码过程。 btoa() 方法用于创建一个 base-64 编码的字符串。该方法使用 "A-Z", "a-z", "0-9", "+", "/" 和 "=" 字符来编码字符串。
atob(),是ascii to binary,用于将ascii码解析成binary数据,即Base64的解码过程。 atob() 方法用于解码使用 base-64 编码的字符串。
2.encodeURIComponent()和decodeURIComponent()
encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。
该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 。 其他字符(比如 :;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。
decodeURIComponent() 函数可对 encodeURIComponent() 函数编码的 URI 进行解码。
3.JSON.stringify()和JSON.parse()
JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串。 JSON.parse() 方法将数据转换为 JavaScript 对象。
关键代码和使用示例
1.加密解密方法
/**
* 加密编码数据 使用 btoa 结合 encodeURIComponent 加密编码数据
* @param data 需要加密编码的数据
*/
export function btoaEncode (data) {
if (!data) {
console.error('加密编码数据不能为空')
return ''
}
try {
data = window.btoa(encodeURIComponent(JSON.stringify(data)))
} catch (e) {
console.error('加密转码异常', e)
}
return data
}
/**
* 解密解码数据 使用 atob 结合 decodeURIComponent 解密解码数据
* @param data 需要解密解码的数据
*/
export function atobDecode (data) {
if (!data) {
console.error('解密解码数据不能为空')
return ''
}
try {
data = JSON.parse(decodeURIComponent(window.atob(data)))
} catch (e) {
console.error('解密解码异常', e)
}
return data
}
复制代码
2.使用示例
// 加密编码后存入 localStorage
localStorage.setItem('user-info', btoaEncode(res.data))
// 取出后解密解码
atobDecode(localStorage.getItem('user-info'))
复制代码