前后端分离,RSA加密传输方案

1.原理

RSA是一种非对称加密算法。通过生成密钥对,用公钥加密,用私钥解密。对于前后端分离的项目,让前端获取到公钥对敏感数据加密,发送到后端,后端用私钥对加密后的数据进行解密即可。

2.实现

RSA工具类:提供秘钥对生成、公钥获取、私钥解密的方法。

java 复制代码
public class RSAUtil {
    
   private final static Logger logger = LoggerFactory.getLogger(RSAUtil.class);
   
   private static final String RSA = "RSA";  
   private static final int KEY_SIZE = 2048; 

   private static ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
   // Bouncy Castle加密库提供的一个类,用于为Java提供加密服务
   private static final BouncyCastleProvider BOUNCY_CASTLE_PROVIDER = new BouncyCastleProvider();
   
   // 密钥对生成
   static void createKey() throws Exception{
      KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA, BOUNCY_CASTLE_PROVIDER);
      keyPairGenerator.initialize(KEY_SIZE, new SecureRandom());
      ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
      objectOutputStream.writeObject(keyPairGenerator.generateKeyPair());
      objectOutputStream.close();
   }
   
   // 公钥获取
   public static RSAPublicKey getPublicKey() throws Exception{
      return (RSAPublicKey) getKeyPair().getPublic();
   }
   
   // 读取,有密钥对则获取公钥,无密钥对则创建密钥对再获取公钥
   static KeyPair getKeyPair()throws Exception{
      if(byteArrayOutputStream.size() == 0){
         synchronized (byteArrayOutputStream) {
            createKey();
         }
      }
      ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());  
      ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);  
      KeyPair keyPair= (KeyPair) objectInputStream.readObject();  
      objectInputStream.close();  
      byteArrayInputStream.close();  
      return keyPair;  
    }
    
   static byte[] decryptByPrivateKey(byte[] encrypttext){
        try {
            Cipher ci = Cipher.getInstance(RSA, BOUNCY_CASTLE_PROVIDER);
            ci.init(Cipher.DECRYPT_MODE, getKeyPair().getPrivate());
            return ci.doFinal(encrypttext);
        }  catch (Exception e) {
         logger.error(e.getMessage(), e);
        }
        return null;
    }
    
   // 接收一个String类型,私钥解密
   public static String decodeString(String string){
        try {  
            byte[] input = Base64.getDecoder().decode(string); // 解码Base64字符串为字节数组  
            byte[] raw = decryptByPrivateKey(input); // 使用私钥解密数据  
            return new String(raw, StandardCharsets.UTF_8); // 直接将字节数组转换为UTF-8字符串  
        } catch (Exception e) {  
            logger.error("解析失败", e);  
            return "";  
        }
   } 
   
}

为前端提供一个获取公钥的接口

java 复制代码
@GetMapping("getRSAPublickey")
public Result<?> getRSAPublickey() {
    Map key = new HashMap();
    try {
        // 通过提供模数和公共指数,可以间接地提供公钥,同时保持安全性。
        String modulus = RSAUtil.getPublicKey().getModulus().toString(16);
        String publicExponent = RSAUtil.getPublicKey().getPublicExponent().toString(16);
        key.put("m", modulus);
        key.put("e", publicExponent);
    } catch (Exception e) {
    }
    return Result.ok(key);
}

前端需要导入一个适合前端使用的RSA加密库。利用获取到的模数和公共指数创建RSA公钥对象,对敏感数据加密。

html 复制代码
<html>
  <script src="rsa.js"></script>
  <body>
    <script>
      window.encryptStr = function (m, e, str) {
        var rsa = new RSAKey()
        rsa.setPublic(m, e)
        return rsa.encrypt(str)
      }
    </script>
  </body>
</html>

后端接收到前端利用RSA加密后的字符串后,直接调用RSAUtil进行解密,得到原文。

java 复制代码
String password = RSAUtil.decodeString(pram.getPassword());

需要注意的是,前端加密只是数据传输过程中的一部分安全措施。为了确保数据的安全性,还需要在后端服务器进行相应的安全措施,例如验证用户身份、使用HTTPS协议进行通信等。

相关推荐
海螺姑娘的小魏6 分钟前
Effective C++ 条款 16:成对使用 `new` 和 `delete` 时要采取相同形式
开发语言·c++
neter.asia25 分钟前
C# 窗体应用程序嵌套web网页,基于谷歌浏览器内核(含源码)
开发语言·c#
苹果醋333 分钟前
Vue3响应式数据: 深入分析Ref与Reactive
java·运维·spring boot·mysql·nginx
2301_8091774742 分钟前
sqoop,flume草稿
开发语言
缘友一世1 小时前
JAVA代理模式和适配器模式
java·代理模式·适配器模式
轻浮j1 小时前
Sentinel底层原理以及使用算法
java·算法·sentinel
it噩梦1 小时前
springboot 工程使用proguard混淆
java·spring boot·后端
潜意识起点1 小时前
Java数组:静态初始化与动态初始化详解
java·开发语言·python
竹影卿心1 小时前
Java连接HANA数据库
java·数据库·windows
Abelard_1 小时前
LeetCode--347.前k个高频元素(使用优先队列解决)
java·算法·leetcode