对于前端来说,加密是一个老生常谈的话题。现在的加密方法和js库也是层出不穷。最近公司项目到了收尾阶段,所以想做一些其他的工作,决定把接口返回的数据简单的加密一下,以至于接口被拦截时,数据不那么赤裸裸的显示别人面前,就想到了用base64的方式。

虽然base64跟其他比较有名的rsa,hash等加密方法比起来显得不太专业,但相比其他复杂的库来说,代码量少,运算量小,并且还能加密解密都自己实现。并且,从开发的角度来说,如果前后端再约定一个一定的打乱顺序,拿到之后自己再重组解密,那么,破解还是不那么容易的。另一方面来说,我们的目的并不是为了别人无法破解(从理论上说,只要能解密的加密,对攻击者来说都只是时间问题),并且太过敏感的数据,我们一般是不会暴露在前端的。虽然 window 自带了 atob  和 btoa,但是不支持低版本浏览器,也不支持中文。如果你只是加密密码这些不含中文字符的内容,可以简单的使用下面的兼容代码:

既然window自带的无法满足我们的需求,那我们就只能自己来完成这一转换功能了。在进行代码编写之前,我们先来了解一下base64是啥,以及如何转换,可帮助我们理解最后完成的代码。

什么是base64

base64是用规定的64种字符来表示任意二进制数据的一种编码格式,而且这64种字符均是可见字符,而之所以要是可见的是因为在不同设备上处理不可见字符时可能发生错误。通常,电子邮件数据、公钥证书会经常使用。

base64编码原理

我们知道单个字符一般用一个字节就可以表示(中文等其他特殊文字除外),而一个字节由8位二进制数构成。那么base64编码中,是将每6位二进制作为一个单位解析后参照字符集的索引就可以得到编码后的字符。举个例子:

但是我们发现一个问题,就是我们单个字符是8位二进制,而base64编码时需要以6位二进制数位单位进行编码。那么多余的2位怎么去处理呢?看下面的例子

通过上面的例子我们可以发现,base64编码时会将二进制通过在末尾补0的方式使其位数满足24的倍数。这样刚好能够编码出至少4个字符。从上面的栗子中我们可以看到=号的数量刚好是缺少2个字节数的数量,而g则是因为多余的2位二进制数补了4个0后编码成了g。所以我们就可以看到这样的编码了。如果还不理解再举一个例子:

有了理论知识后,我们接下来要做的,就是解析字符串为二进制数据了。我们知道,对于 js 中的字符串(不带中文字符)来说,刚好有个 charCodeAt()  方法返回指定字符的 unicode  编码对应的数值,这个数值就是二进制数表示的数值,我们只需要将其转换为二进制即可。

英文字符已经搞定了,那中文又该如何处理呢?直接上代码:

到这里,解析成base64的方法已经实现了,那base64转字符串就是一个逆解析的过程,这里就不再赘述了。

最后,附上完整代码。

 

使用方法:

好了,到这里我们的banse64与字符串的互转算是完成了,从某种意义上来说,这已经是一种加密了。那我们还可以再做复杂一点,就以上面代码为例,后端返回数据的时候,可以把转成的字符串做一下重新组合,比如,把后六位截取了放到最前面:

这样,一个简单的加密就成功了。

思考一下,如果我们把字符串的重组规则弄得足够复杂,是不是也基本满足了一定的加密需求。以我个人在项目中自定义的一个加密规则为例:

加密前的明文为:admin321$,加密后的密文为NE5vUkhGellXUnRhVzR6TWpFaw==;

加密前的明文为:321$admin,加密后的密文为MWtLYVRBMk16SXhKR0ZrYldsdQ==;

并且每次加密结果都不一样,你能一下子看出怎么加密的,简单的就破解它吗。