最近几天在给自己做的app添加一个加密解密功能,看了一些文章,最终决定使用RSA算法来做。还是在一些问题上困扰了几天,终于搞来搞去还是搞出来了。
一、模块选用
node-rsa模块:后端用的nodejs(express)框架,因为crypto模块需要利用OpenSSL库来实现它的加密技术,我选择了 node-rsa模块;
jsencrypt模块:前端自然是用jsencrypt模块,这个也可以用script引入html使用,因为我是用webpack写的,所以直接在文件中引入jsencrypt模块;
二、前后端代码实现
后端代码:
const express = require('express'); const app = express(); const NodeRSA = require('node-rsa'); const newkey = new NodeRSA({b: 1024}); newkey.setOptions({encryptionScheme: 'pkcs1'}); //因为jsencrypt自身使用的是pkcs1加密方案,只有从后台改咯let public_key = newkey.exportKey('pkcs8-public'),//公钥, private_key = newkey.exportKey('pkcs8-private'); //私钥 console.log({a:public_key,b:private_key})let pubkey = new NodeRSA(public_key), prikey = new NodeRSA(private_key); pubkey.setOptions({encryptionScheme: 'pkcs1'});//因为jsencrypt自身使用的是pkcs1加密方案,只有从后台改咯 prikey.setOptions({encryptionScheme: 'pkcs1'});//因为jsencrypt自身使用的是pkcs1加密方案,只有从后台改咯// 加密 && 解密方法 // let encrypted = pubkey.encrypt(yourstring,'base64'); // var decrypted = prikey.decrypt(encrypted, 'utf8'); let body_parse = function(req){ return JSON.parse(Object.keys(req.body)[0]+req.body[Object.keys(req.body)[0]])}let decrypted = function(req,eve,_attr){ var _user = body_parse(req)[_attr],//_attr是传输回来的对象中装有密文的属性 str = Buffer.from(_user, 'base64').toString().replace(/%$#%/g,"+");//转回符号'+' var data = JSON.parse(prikey.decrypt(str, 'utf8')); //后端解密 if(eve){ eve(data); }}
前端代码:
const JSEncrypt = require("jsencrypt"); // 引入模块const obj = {username:"sweetheart",password:"mylove"};const jencrypt = new JSEncrypt.JSEncrypt(); // 实例化加密对象localStorage.setItem("crosspu",data['crosspu']);jencrypt.setPublicKey(localStorage.getItem("crosspu")); var encryptoPasswd = jencrypt.encrypt(JSON.stringify(obj)) // 加密明文//因为base64传输到后台的时候"+"号被会转为空格,故而需要先替换,后台解析的时候转回来var rr ={imfor:btoa(encryptoPasswd).replace(/\+/g,"%$#%")}
三、重要部分
在一些地方还是走了写弯路;
1、key.setOptions({encryptionScheme: 'pkcs1'});(key是new NodeRSA()的值);
2、密文先转为base64传输的时候先把"+"转为一个不常见的字符串,到后端取用的时候转回;
上述仅记录主要的部分,最近还在写自己的app,全面的测试只有放到后面了