背景:最近在学习react native ,由于目前已经发布的app(ios、安卓)有rsa加密的地方,所以 就尝试用 RN 实现下,加解密流程是 服务端生成 公、私钥,然后存储私钥,给前端发送公钥,前端用公钥加密后将数据传给服务端,服务端解密。此文就不说如何解密了。
所用的rsa库 我是直接将git上的库(如图1 的三个文件)放到我的RN项目文件里。
首先下载 buffer 包,此包功能很强大感兴趣的可以多了解了解。先用终端进入到RN 项目的根目录下,然后敲入
命令 npm install buffer --save
在此说明下 --save 是为了在自己项目主目录下的package.json里能看到自己依赖的包。如图( package.json 的截图 ):红色框里的buffer就是下载的。另外‘react’ 和‘react-native’ 是项目init时自带的 ( 如何init一个新的项目参考 图2,图片截取自 react中文网-搭建开发环境) 。其余没用红框框的,无需关注。项目中rsa并没用到(是尝试其他rsa 加解密时下载的依赖库)。
buffer 下载后,会在 node_modules 目录里。
代码之前先说下rsa。
1、我们要坚信的认为rsa的加密算法一定是一致的。 以此,我们找库的关于加解密的算法部分一定是没问题的,不管什么平台的,什么语言的。(前提,这个库只要有人成功过)
2、即使同一个公钥,明文相同,加密后的密文也不相同,(这个地方让我白白浪费了大半天时间),至于什么原因不同,有兴趣的可以google了解下。
3、rsa 加密有两中,一种是根据modulus,一种根据publickey。本文说的是根据modulus,publickey 也有对应的库,在此就不说了。推荐个库 node-rsa 我没试过,不知道是否可以。
4、modulus 会通过计算生成 公钥,这里有个有个bignum的概念。jsbn.js 文件里可以看到。而用publickey 话,直接使用即可。
闲话少说,上代码。
import RSAKey from './Utils/RSA/rsa1/rsa'
import {Buffer} from 'buffer'
RSAKey 的引用,根据它的目录结构来。 根目录-Utils-RSA-rsa1 如图3 RN3 就是该项目的根目录。 这里目录引用,主要给初学者强调下,如果已经了解可以忽略。
buffer 上面已经提到,装在了node_modules目录里,所以这样引用就行。
接着下面的代码
// 服务器返回的 modulus 串
let modulusKey1 = 'AICUXv5CXjBmz09IeybFBxNjd0jrqWN/d08mv5UvbAoYEzdDisP+C4C2oAMk9VB3hY9BBswu9efv72UayDpCL7e9RVs0WZ7ghp7rNxDjk99rcDP8K537iqDaLRTcFXPKvgXKnxlrz7AOJblVVfmf68sZDd9JEQvLsCwaJFOYkj/X';
// buffer的创建,这里说下,由于我们服务器返回的是base64,所以buffer的第二个参数就是 ‘base64’,具体用法可以参考 buffer api
let modulusKey2 = new Buffer(modulusKey1, 'base64');
// 这一步是将服务器返回的数据转成hex,为什么要这么做呢,因为我们用的rsa库的参数是hex格式, 这个 rsa.js 源码里有提到,或者 __tests__ 文件夹里的index.spec.js 的事例也提到了(第5、6行),事例里的publicKey 就是我说的modulus,只是作者起的变量名叫publicKey。
let modulusKey3 = modulusKey2.toString('hex');
// 准备好参数对象,这里提下,n 和 e 是与rsa modulus 方式必须的参数。如果你看到 其他平台有提到 ‘AQAB’ 和这里的 ‘10001’ 是一样的。你可以尝试将AQAB转成hex格式看看。
let ConsultPublicKey = {n:modulusKey3,e:'10001'};
// 加密的明文
let randomKey = 'aaabbbcccdddeeefffggghhh';
// 创建rsa加、解密对象
let rsaPublicKey = new RSAKey();
// 设置秘钥,这注意下,需要将ConsultPublicKey 对象转成json字符串,因为setPublicString参数类型是json字符串。
rsaPublicKey.setPublicString(JSON.stringify(ConsultPublicKey));
// 进行加密操作
let randomKeyRsa = rsaPublicKey.encrypt(randomKey);
// 将加密后的数据 创建buffer, encrypt方法的返回值就hex格式的
let tempBuffer = new Buffer(randomKeyRsa,'hex');
// 将数据转成base64
let tempBuffer3= tempBuffer.toString('base64');
// 注释: tempBuffer3 就是服务端要的加密数据了。
我们看下服务端的代码。由于服务端不是我开发的,库什么的也不清楚,但是还是那句话,rsa 加密的库的算法什么的一定都是统一的。所以你找个有人成功过的库就Ok了。这里我只贴个给前端传的数据处理部分的代码。 如图4
以上是代码部分。
希望以上部分对你有帮助,如有什么问题,留言联系。