因公司做的产品为金融项目,所以对数据安全性有很高要求,因为项目中的数据都会通过3DES 对称加密,和RSA非对称加密进行数据传输。
在这里先简单介绍一下什么是对称加密和非对称加密
对称加密:对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥加密。
非对称加密:对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。(ps:公钥放在客户端,用于加密;私钥放在服务器端,用于解密)
https://blog.csdn.net/qq_34024275/article/details/82424100
这里前端加解密的工具库我选择用Google的Cryptojs库,里面有多种加密方式,因为小程序对主包有大小限制,这里我只选择引入3des加密需要的js文件,下面附上github下载地址:
下载地址:https://github.com/sytelus/CryptoJS
下载下来我们会得到一个CryptoJS-master项目,而我们需要的js文件在components目录下,而我们需要找到我们3DES/ECB加密解密需要的文件: tripledes.js,mode-ecb.js 这两个文件。
如果项目主包大小太大了,可以选择min压缩版的。
因为小程序开发完全是使用模块化开发,不同于H5,因而我们需要在项目中引入这两个文件需更添加一点代码。
第一步:首先我们将这两个文件放到同一目录下面 ,然后在 tripledes.js 文件底部将CryptoJS对象声明出去供外部使用,加上下面代码:
module.exports = {
CryptoJS: CryptoJS
}
第二步:在mode-ecb.js文件头部引入CryptoJS对象,然后将CryptoJS.mode.ECB声明出去。这里mode-ecb.js文件代码量比较少,就整个贴出来:
var CryptoJS = require('./tripledes.js').CryptoJS //引入CryptoJS对象
CryptoJS.mode.ECB = (function () {
var ECB = CryptoJS.lib.BlockCipherMode.extend();
ECB.Encryptor = ECB.extend({
processBlock: function (words, offset) {
this._cipher.encryptBlock(words, offset);
}
});
ECB.Decryptor = ECB.extend({
processBlock: function (words, offset) {
this._cipher.decryptBlock(words, offset);
}
});
return ECB;
}());
module.exports = {
CryptoJS_mode_ECB : CryptoJS.mode.ECB //声明加密mode
}
第三步:创建加解密工具类crypto.js
//引入js文件
//@author ethan
import {CryptoJS} from '../js/tripledes.js'
import {CryptoJS_mode_ECB} from '../js/mode-ecb.js'
//3DES字符串加密
export const getEncodeStrData = (str,key) => {
var keyHex = CryptoJS.enc.Utf8.parse(key);
var encrypted = CryptoJS.TripleDES.encrypt(str, keyHex, {
mode: CryptoJS_mode_ECB,
padding: CryptoJS.pad.Pkcs7 //后端pkcs5填充,前端对应pkcs7
});
return encrypted.toString()
};
//3DES字符串解密
export const getDecodeStrData = (str,key) => {
var keyHex = CryptoJS.enc.Utf8.parse(key);
var decrypted = CryptoJS.TripleDES.decrypt(str, keyHex, {
mode:CryptoJS_mode_ECB,
padding: CryptoJS.pad.Pkcs7 //后端pkcs5填充,前端对应pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8)
};
第四步:java后端创建加解密工具类DesEncryptAndDecrypt.java
package com.uaf.wxAppWeb.utils;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
public class DesEncryptAndDecrypt {
/**
* 使用key作为加密秘钥进行加密
* @param src
* @param key
* @return
*/
@SuppressWarnings("static-access")
public static String encryption3DES(String src, String key) {
try {
DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey securekey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, securekey);
byte[] b = cipher.doFinal(src.getBytes("UTF-8"));
Base64Util encoder = new Base64Util();
String str = encoder.encode(b).replaceAll("\r", "").replaceAll("\n", "");
return str;
} catch (Exception e) {
LogUtils.dbAndTextError("3DES加密异常", e);
return "";
}
}
/**
* 使用key作为解密秘钥进行解密
* @param src
* @param key
* @return
*/
@SuppressWarnings("static-access")
public static String decryptThreeDESECB(String src, String key) {
byte[] retByte = null;
try {
// --通过base64,将字符串转成byte数组
Base64Util decoder = new Base64Util();
byte[] bytesrc = decoder.decode(src);
// --解密的key
DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey securekey = keyFactory.generateSecret(dks);
// --Chipher对象解密
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, securekey);
retByte = cipher.doFinal(bytesrc);
return new String(retByte, "UTF-8");
} catch (Exception e) {
LogUtils.dbAndTextError("3DES解密异常", e);
}
return "";
}
}
到这里3DES加密的工具类算构建完成,这里比较注意的地方是一定要在mode-ecb.js文件头部引入CryptoJS对象
总得来说谷歌CryptoJS库使用起来还是很方便,这篇文章是为了记录工作中遇到的问题,如果发现有问题欢迎留言一起探讨。