1. 首页
  2. 后端

AES和RSA混搭风格

  AES和RSA混搭风格

===========

为什么要使用AESxRSA混搭风格

首先我们必须要了解常见的加密算法有哪些特点,并选择合适的解决方案来满足我们的安全需求,本文内容着重探讨的是AESxRSA组合加密的实现方案。

常见加密算法

本次重点介绍AES和RSA加密算法的混搭方式是如何实现高效、安全、快捷的加密方式以满足业务的需求。

如果对常见密码算法做一个分类,那么结构图大概如下所示:

image.png

什么是 AES 加密 和 RSA 加密?

image.png

AES(Advanced Encryption Standard,高级加密标准)

AES 是一种对称加密算法,即加密和解密使用相同的密钥。AES 的密钥长度可以选择 128 位、192 位或 256 位。AES 的加密过程包括多轮的重复操作,包括置换、替换、行移位和列混合等。AES算法具有较高的安全性和运算效率,广泛应用于保护数据的机密性。

image.png
RSA(由发明者Rivest、Shamir、Adleman的姓氏首字母组成)

RSA 是一种非对称加密算法,即加密和解密使用一对不同的密钥,分别称为公钥和私钥。公钥用于加密数据,私钥用于解密数据。RSA 算法的安全性基于大数分解问题,密钥长度通常选择 1024 位、2048 位或更长。RSA 算法用于保护数据的机密性、确保数据的完整性和实现数字签名等功能。

AES 加密 和 RSA 加密的区别是什么?

对称加密与非对称加密:AES 是对称加密算法,加密和解密使用相同的密钥;而RSA 是非对称加密算法,加密和解密使用不同的密钥。

效率方面:AES 加密和解密的运算速度较快,消耗资源较少;而 RSA 算法由于涉及大数计算,运算速度较慢,消耗资源较多。

应用场景:AES 适用于加密大量数据,如文件加密、网络通信加密等;RSA 常用于加密较小的数据,如密钥交换、数字签名等,。

加密方式比较:

  • 针对名称:采用单加密方法,同一个密码可以同时用来解密 。常见的针对名称算法有DES3DESAES
  • 非针对性加密,需要两个秘钥进行加密解密,这两个密钥是公开密钥(public key,简称公钥)私有密钥(private key,简称私钥) 。常见的非针对性加密算法有RSAElgamalECC

| 名称 | RSA | AES |
| — | — | — |
| 加密方式 | 非对称 | 对称 |
| 秘钥的使用 | 不同的密钥用于加密和解密数据 | 同一个密钥用于加密和解密数据 |
| 最小长度 | 512 位 | 128 位 |
| 秘钥长度 | 512 位, 1024 位,2048 位或更长 | 10–128 位, 12–192 位, 14–256 位 |
| 安全性 | 较高 | 一般 |
| 效率 | 慢 | 快 |

AESxRSA加解密流程

image.png

  1. 发送方首先通过AES算法生成AES秘钥。
  2. 发送方通过AES秘钥对原始的数据内容进行加密后产生密文。
  3. 发送方通过RSA的私有秘钥对AES秘钥进行加密得到加密后的秘钥。
  4. 发送方将加密后的密文和密钥发送给接收方。
  5. 接收方通过RSA公钥对加密后的秘钥进行解密得到AES的秘钥。
  6. 接收方通过ESA秘钥解密加密后的密文数据。

AESxRSA Java实现代码

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class RSAAndAESCombination {

    // RSA密钥长度
    private static final int RSA_KEY_SIZE = 2048;

    // AES密钥长度
    private static final int AES_KEY_SIZE = 128;

    // 用于AES加密的密钥别名
    private static final String AES_KEY_ALIAS = "aesKey";

    // RSA密钥生成
    public static KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(RSA_KEY_SIZE);
        return keyPairGenerator.generateKeyPair();
    }

    // AES密钥生成
    public static SecretKey generateAESKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(AES_KEY_SIZE);
        return keyGenerator.generateKey();
    }

    // 使用RSA公钥加密AES密钥
    public static String encryptAESKeyWithRSA(SecretKey aesKey, PublicKey rsaPublicKey) throws Exception {
        Cipher rsaCipher = Cipher.getInstance("RSA");
        rsaCipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey);
        byte[] encryptedAesKey = rsaCipher.doFinal(aesKey.getEncoded());
        return Base64.getEncoder().encodeToString(encryptedAesKey);
    }

    // 使用AES密钥加密数据
    public static String encryptDataWithAES(String data, SecretKey aesKey) throws Exception {
        Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // 注意:ECB模式仅用于示例,通常建议使用CBC或其他模式
        aesCipher.init(Cipher.ENCRYPT_MODE, aesKey);
        byte[] encryptedData = aesCipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedData);
    }

    // 使用RSA私钥解密AES密钥
    public static SecretKey decryptAESKeyWithRSA(String encryptedAesKey, PrivateKey rsaPrivateKey) throws Exception {
        byte[] decodedAesKey = Base64.getDecoder().decode(encryptedAesKey);
        Cipher rsaCipher = Cipher.getInstance("RSA");
        rsaCipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey);
        byte[] decryptedAesKey = rsaCipher.doFinal(decodedAesKey);
        return new SecretKeySpec(decryptedAesKey, "AES");
    }

    // 使用AES密钥解密数据
    public static String decryptDataWithAES(String encryptedData, SecretKey aesKey) throws Exception {
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // 注意:ECB模式仅用于示例,通常建议使用CBC或其他模式
        aesCipher.init(Cipher.DECRYPT_MODE, aesKey);
        byte[] decryptedData = aesCipher.doFinal(decodedData);
        return new String(decryptedData, StandardCharsets.UTF_8);
    }

    // 主函数,用于测试
    public static void main(String[] args) throws Exception {
        // 生成RSA密钥对
        KeyPair rsaKeyPair = generateRSAKeyPair();
        PublicKey rsaPublicKey = rsaKeyPair.getPublic();
        PrivateKey rsaPrivateKey = rsaKeyPair.getPrivate();

        // 生成AES密钥
        SecretKey aesKey = generateAESKey();
        // 将密钥转换为字节数组
        byte[] encoded = aesKey.getEncoded();

        // 通常,密钥不会直接以字节形式存储或传输,而是会进行Base64编码
        String base64EncodedKey = Base64.getEncoder().encodeToString(encoded);
        System.out.println("AES Key: " + base64EncodedKey);

        // 待加密的数据
        String originalData = "Hello, RSA and AES Encryption!";
        System.out.println("原始数据: " + originalData);

        // 使用RSA公钥加密AES密钥
        String encryptedAesKey = encryptAESKeyWithRSA(aesKey, rsaPublicKey);
        System.out.println("RSA私钥加密 AES Key: " + encryptedAesKey);

        // 使用AES密钥加密数据
        String encryptedData = encryptDataWithAES(originalData, aesKey);
        System.out.println("AES加密后的数据: " + encryptedData);

        // 使用RSA公钥解密
        SecretKey secretKey = decryptAESKeyWithRSA(encryptedAesKey, rsaPrivateKey);
        // 将密钥转换为字节数组
        byte[] encodeds = secretKey.getEncoded();

        // 通常,密钥不会直接以字节形式存储或传输,而是会进行Base64编码
        String base64EncodedKeys = Base64.getEncoder().encodeToString(encoded);

        // 打印Base64编码的密钥
        System.out.println("RSA私钥加密 AES Key: " + base64EncodedKey);

        //AES解密后的数据
        String decryptedData = decryptDataWithAES(encryptedData, secretKey);
        System.out.println("AES解密后的数据: " + decryptedData);

    }
}

代码执行结果

AES Key: sMKUkf/sJD6S4lB/rrA0Dw==

原始数据: Hello, RSA and AES Encryption!

RSA私钥加密 AES Key: CYhFrJ7p2yzr07fkYj7F0hmX4SNDbHjfrFBW8jjFnhbqFba0N0X0Q2NVhBraLC6M36jQoAWDQwoYVhK6/b1+H+pElP+HTKhj2KLi5oCddP57+6VYRKF13WW5mNWYejA7M0ieujqhoXJzfo77KJdsZmHGl3lBfVh3bHyzTW3jjWPEN4rm/fJ7b+NaaruuphMgWUgKJLJsj+TPXkkhwg6U0hJ2ahxiTbjcvlWHP+f6MYy0KdSTB1Osc5RqedMUoHHLob6osXsL/Q6nwKYyJsop0PvXtH1zfNx03wsDHXWAceolBGlSwcLT2d4Z1VsAfHgd9fMJNIRGGl61WiGs+3TAsw==

AES加密后的数据: ozoaVuXVGnGzREXEYF1xqXMEsJbzUIdTC/4JygTNJe8=

RSA私钥加密 AES Key: sMKUkf/sJD6S4lB/rrA0Dw==

AES解密后的数据: Hello, RSA and AES Encryption!

原文链接: https://juejin.cn/post/7383879646327308300

文章收集整理于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除,如若转载,请注明出处:http://www.cxyroad.com/17150.html

QR code