一: 常见加密算法

1.对称加密

使用的密钥只有一个,发送和接收双方都使用这个密钥对数据进行加密和解密。这就要求加密和解密方事先都必须知道加密的密钥。其优点是算法公开、计算量小、加密速度快、加密效率高;缺点是密钥泄露之后,数据就会被破解。一般不推荐单独使用。根据实现机制的不同,常见的算法主要有AESChaCha203DES等。

2.非对称加密

它需要两个密钥,一个称为公开密钥 (public key),即公钥;另一个称为私有密钥 (private key),即私钥。
他俩是配对生成的,就像钥匙和锁的关系。因为加密和解密使用的是两个不同的密钥,所以这种算法称为非对称加密算法。其优点是算法强度复杂、安全性高;缺点是加解密速度没有对称加密算法快。常见的算法主要有RSAElgamal等。

3.散列算法

散列算法又称散列函数、哈希函数,是把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定成特定长度的值。一般用于校验数据的完整性,平时我们下载文件就可以校验 MD5 来判断下载的数据是否完整。常见的算法主要有 MD4MD5SHA 等。

二:方案

单单使用对称加密

使用两套非对称加密,

上传数据-客户端用公钥加密,下载数据-客户端用私钥解密秘钥更新比较麻烦

对称加密与非对称结合:

上传数据时:

  • 客户端用随机生成秘钥对敏感数据进行对称加密,
  • 从服务端获取非对称加密的 公钥,
  • 对称加密的秘钥进行非对称加密

下载数据:

  • 服务端用对称加密对数据进行加密

数据传输加密- - 图1

总结:

方案二比较简单,但是需要维护两套公钥和私钥,当公钥变化的时候,必须通知对方,灵活性比较差。方案三相对方案二来说,密钥 1 随时可以变化,并且不需要通知服务端,相对来说灵活性、安全性好点并且方案三对内容是对称加密,当数据量大时,对称加密的速度会比非对称加密快。所以本文采用方案三给予代码实现。

三: 代码实现

对称加密库使用的是 AES,非对称加密库使用的是RSA。

前端:

  1. // npm 引入
  2. npm install crypto-js
  3. //utils包下的index文件中增加解密与加密方法
  4. const CryptoJS = require('crypto-js')
  5. /**
  6. * aes加密方法
  7. * @param {string} text 待加密的字符串
  8. * @param {array} key 加密key
  9. */
  10. export function aesEncrypt(text, key) {
  11. // var message = JSON.stringify(data);//加密后的字符窜
  12. key = CryptoJS.enc.Utf8.parse(key)
  13. var encryptedData = CryptoJS.AES.encrypt(text, key, {
  14. mode: CryptoJS.mode.ECB, // ECB加密模式 根据后端采用的模式更改
  15. padding: CryptoJS.pad.Pkcs7
  16. })
  17. return encryptedData.toString()
  18. }
  19. /**
  20. * aes解密方法
  21. * @param {string} encryptedHex 加密的字符串
  22. * @param {array} key 加密key
  23. */
  24. export function aesDecrypt(encryptedHex, key) {
  25. key = CryptoJS.enc.Utf8.parse(key)
  26. var decrypt = CryptoJS.AES.decrypt(encryptedHex, key, {
  27. mode: CryptoJS.mode.ECB,
  28. padding: CryptoJS.pad.Pkcs7
  29. })
  30. return CryptoJS.enc.Utf8.stringify(decrypt).toString()
  31. }
  32. /**
  33. * 随机生成秘钥
  34. */
  35. export function getRandomKey(n) {
  36. var chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
  37. if (n == null) {
  38. n = 16
  39. }
  40. var res = ''
  41. for (var i = 0; i < n; i++) {
  42. var id = Math.ceil(Math.random() * 35)
  43. res += chars[id]
  44. }
  45. return res
  46. }

常见错误:

Key length not 128/192/256 bits,key的长度必须要是128,192或者256 位
128 位 对应的是 16 个字节
192 位 对应的是 24 个字节
256 位 对应的是 32 个字节

  1. npm install jsencrypt
  2. //vue页面引入
  3. import { JSEncrypt } from 'jsencrypt'
  4. //页面方法内:
  5. const encrypt = new JSEncrypt()
  6. encrypt.setPublicKey(this.publicKey) //设置公钥
  7. data.secretKey = encrypt.encrypt(secretKey) //非对称加密

java:

java部分是引用的Hutool工具包中的方法

  1. //@Configuration配置类中,配置公私钥 将rsa对象放入容器中
  2. @Bean
  3. public RSA RSAGenfactory(){
  4. return new RSA(privateKey,publicKey);
  5. }
  6. //接口方法中对上传数据进行解析
  7. 引入容器中的RSA对象
  8. @Autowired
  9. RSA rsa;
  10. //非对称解密
  11. String data = rsa.decryptStr(要解密的数据, KeyType.PrivateKey);
  12. //对称解密
  13. SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, data.getBytes());
  14. String repCode = aes.decryptStr(要解密的数据,CharsetUtil.CHARSET_UTF_8);

出处:

敏感数据加密方案以及实现