RSA + AES对前后端数据进行加密

前言

在前后端交互时,常常采取http方式进行传输,而明文传输通常会被网络抓包、反编译等手段得到htpp通讯接地址和参数等。

为了确保信息的安全,在生产中使用了很多种加密手段。 最终采用 AES+RSA 组合进行接口参数加密和解密的方式脱颖而出,成为了当今主流手段。

欢迎关注个人公众号【好好学技术】交流学习

为什么使用RSA + AES混合加密

1.加密介绍

  • RSA加密: 属于非对称加密,公钥用于对数据进行加密,私钥对数据进行解密,两者不可逆。公钥和私钥是同时生成的,且一一对应。比如:客户端拥有公钥,服务端拥有公钥和私钥。客户端将数据通过公钥进行加密后,发送密文给服务端,服务端可以通过私钥和公钥进行解密。
  • AES加密: 属于对称加密,简单点说就是,客户端用密码对数据进行AES加密后,服务端用同样的密码对密文进行AES解密。

2.加密思路

  • 利用 RSA 来加密传输 AES的密钥,用 AES的密钥 来加密数据。
  • 既利用了 RSA 的灵活性,可以随时改动 AES 的密钥;又利用了 AES 的高效性,可以高效传输数据。

3.混合加密原因

  • 单纯的使用 RSA(非对称加密)方式,效率会很低,因为非对称加密解密方式虽然很保险,但是过程复杂,耗费时间长,性能不高;
  • RSA 优势在于数据传输安全,且对于几个字节的数据,加密和解密时间基本可以忽略,所以用它非常适合加密 AES 秘钥(一般16个字节);
  • 单纯的使用 AES(对称加密)方式的话,非常不安全。这种方式使用的密钥是一个固定的密钥,客户端和服务端是一样的,一旦密钥被人获取,那么,我们所发的每一条数据都会被都对方破解;
  • AES有个很大的优点,那就是加密解密效率很高,而我们传输正文数据时,正好需要这种加解密效率高的,所以这种方式适合用于传输量大的数据内容;
  • 基于以上特点,就有了我们混合加密的思路

时序图

加密时序图.png

代码实现

RAS 非对称加密

java
  1. AES加密
package com.fandf.demo.encrypt;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * 功能:AES 工具类
 */
@SuppressWarnings("all")
public class AESUtil {
    private static final Logger logger = LoggerFactory.getLogger(AESUtil.class);

    public final static String KEY_ALGORITHMS = "AES";
    public final static int KEY_SIZE = 128;

    /**
     * 生成AES密钥,base64编码格式 (128)
     *
     * @return
     * @throws Exception
     */
    public static String getKeyAES_128() throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance(KEY_ALGORITHMS);
        keyGen.init(KEY_SIZE);
        SecretKey key = keyGen.generateKey();
        String base64str = Base64.encodeBase64String(key.getEncoded());
        return base64str;
    }

    /**
     * 生成AES密钥,base64编码格式 (256)
     *
     * @return
     * @throws Exception
     */
    public static String getKeyAES_256() throws Exception {
        // 256需要换jar包暂时用128
        String base64str = getKeyAES_128();
        return base64str;
    }

    /**
     * 根据base64Key获取SecretKey对象
     *
     * @param base64Key
     * @return
     */
    public static SecretKey loadKeyAES(String base64Key) {
        byte[] bytes = Base64.decodeBase64(base64Key);
        SecretKeySpec secretKeySpec = new SecretKeySpec(bytes, KEY_ALGORITHMS);
        return secretKeySpec;
    }

    /**
     * AES 加密字符串,SecretKey对象
     *
     * @param key
     * @param encryptData
     * @param encode
     * @return
     */
    public static String encrypt(SecretKey key, String encryptData, String encode) {
        try {
            final Cipher cipher = Cipher.getInstance(KEY_ALGORITHMS);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] encryptBytes = encryptData.getBytes(encode);
            byte[] result = cipher.doFinal(encryptBytes);
            return Base64.encodeBase64String(result);
        } catch (Exception e) {
            logger.error("加密异常:" + e.getMessage());
            return null;
        }
    }

    /**
     * AES 加密字符串,base64Key对象
     *
     * @param base64Key
     * @param encryptData
     * @param encode
     * @return
     */
    public static String encrypt(String base64Key, String encryptData, String encode) {
        SecretKey key = loadKeyAES(base64Key);
        try {
            final Cipher cipher = Cipher.getInstance(KEY_ALGORITHMS);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] encryptBytes = encryptData.getBytes(encode);
            byte[] result = cipher.doFinal(encryptBytes);
            return Base64.encodeBase64String(result);
        } catch (Exception e) {
            logger.error("加密异常:" + e.getMessage());
            return null;
        }
    }

    /**
     * AES 解密字符串,SecretKey对象
     *
     * @param key
     * @param decryptData
     * @param encode
     * @return
     */
    public static String decrypt(SecretKey key, String decryptData, String encode) {
        try {
            final Cipher cipher = Cipher.getInstance(KEY_ALGORITHMS);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] decryptBytes = Base64.decodeBase64(decryptData);
            byte[] result = cipher.doFinal(decryptBytes);
            return new String(result, encode);
        } catch (Exception e) {
            logger.error("加密异常:" + e.getMessage());
            return null;
        }
    }

    /**
     * AES 解密字符串,base64Key对象
     *
     * @param base64Key
     * @param decryptData
     * @param encode
     * @return
     */
    public static String decrypt(String base64Key, String decryptData, String encode) {
        SecretKey key = loadKeyAES(base64Key);
        try {
            final Cipher cipher = Cipher.getInstance(KEY_ALGORITHMS);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] decryptBytes = Base64.decodeBase64(decryptData);
            byte[] result = cipher.doFinal(decryptBytes);
            return new String(result, encode);
        } catch (Exception e) {
            logger.error("加密异常:" + e.getMessage());
            return null;
        }
    }
}
  1. RSA加解密
package com.fandf.demo.encrypt;

import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;

import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * SHA256withRSA 工具类
 */
@SuppressWarnings("all")
public class RSAUtil {
    private static final Logger logger = LoggerFactory.getLogger(RSAUtil.class);

    // MAX_DECRYPT_BLOCK应等于密钥长度/8(1byte=8bit),所以当密钥位数为2048时,最大解密长度应为256.
    // 128 对应 1024,256对应2048
    private static final int KEYSIZE = 2048;
    // RSA最大加密明文大小
    private static final int MAX_ENCRYPT_BLOCK = 117;
    // RSA最大解密密文大小
    private static final int MAX_DECRYPT_BLOCK = 128;

    // 不仅可以使用DSA算法,同样也可以使用RSA算法做数字签名
    private static final String KEY_ALGORITHM = "RSA";
    private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";

    // 默认种子
    public static final String DEFAULT_SEED = "$%^*%^()(ED47d784sde78";
    // 编码格式
    private static final String CODE_FORMATE_UTF8 = "UTF-8";

    // - - - - - - - - - - - - - - - - - - - - RSA 生成秘钥对 - - - - - - - - - - - - - - - - - - - - //

    /**
     * 生成密钥对:Base64 转码的字符串
     *
     * @param key
     * @return
     */
    public static Map<String, String> initKeyBase64Str() throws Exception {
        Map<String, String> map = new HashMap<>(2);
        Map<String, Key> keyMap = initKey();
        PublicKey publicKey = (PublicKey) keyMap.get("PublicKey");
        PrivateKey privateKey = (PrivateKey) keyMap.get("PrivateKey");
        map.put("PublicKey", new String(Base64.encodeBase64(publicKey.getEncoded())));
        map.put("PrivateKey", new String(Base64.encodeBase64(privateKey.getEncoded())));
        logger.info("生成密钥 = " + JSON.toJSONString(map));
        return map;
    }

    /**
     * 生成默认密钥
     *
     * @return 密钥对象
     */
    public static Map<String, Key> initKey() throws Exception {
        return initKey(DEFAULT_SEED);
    }

    /**
     * 生成密钥对:若seed为null,那么结果是随机的;若seed不为null且固定,那么结果也是固定的;
     *
     * @param seed 种子
     * @return 密钥对象
     */
    public static Map<String, Key> initKey(String seed) throws Exception {
        KeyPairGenerator keygen = KeyPairGenerator.getInstance(KEY_ALGORITHM);

        // 如果指定seed,那么secureRandom结果是一样的,所以生成的公私钥也永远不会变
        SecureRandom secureRandom = new SecureRandom();
        secureRandom.setSeed(seed.getBytes());
        // Modulus size must range from 512 to 1024 and be a multiple of 64
        keygen.initialize(KEYSIZE, secureRandom);

        // 生成一个密钥对,保存在keyPair中
        KeyPair keys = keygen.genKeyPair();
        PublicKey publicKey = keys.getPublic();
        PrivateKey privateKey = keys.getPrivate();

        // 将公钥和私钥保存到Map
        Map<String, Key> map = new HashMap<>(2);
        map.put("PublicKey", publicKey);
        map.put("PrivateKey", privateKey);
        logger.info("生成密钥 = " + JSON.toJSONString(map));
        return map;
    }

    // - - - - - - - - - - - - - - - - - - - - RSA 加密、解密 - - - - - - - - - - - - - - - - - - - - //

    /**
     * 获取公钥 PublicKey 信息
     *
     * @param 公钥
     * @return
     */
    public static PublicKey getPublicKey(String pubKeyStr) throws Exception {
        byte[] publicKeys = Base64.decodeBase64(pubKeyStr);
        X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeys);
        KeyFactory mykeyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicKey = mykeyFactory.generatePublic(publicKeySpec);
        logger.info("传入的公钥为:【" + pubKeyStr + "】,转义后的公钥为:【" + publicKey + "】");
        return publicKey;
    }

    /**
     * 公钥加密,指定 RSA 方式的 PublicKey 对象
     *
     * @param str       加密字符串
     * @param publicKey 公钥
     * @return
     */
    public static String encrypt(String str, String publicKey) throws Exception {
        // base64编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(decoded));
        // RSA加密
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes(CODE_FORMATE_UTF8)));
        return outStr;
    }

    /**
     * 公钥加密,任意 PublicKey 对象
     *
     * @param publicKey
     * @param encryptData
     * @param encode
     */
    public static String encrypt(PublicKey publicKey, String encryptData, String encode) throws Exception {
        if (publicKey == null) {
            throw new Exception("加密公钥为空,请设置。");
        }
        try {
            final Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] output = cipher.doFinal(encryptData.getBytes(encode));
            return Base64.encodeBase64String(output);
        } catch (Exception e) {
            logger.info("加密异常:" + e.getMessage());
            return null;
        }
    }

    /**
     * 私钥解密,指定 RSA 方式的 PrivateKey 对象
     *
     * @param str        加密字符串
     * @param privateKey 私钥
     * @return
     */
    public static String decrypt(String str, String privateKey) throws Exception {
        // 64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes(CODE_FORMATE_UTF8));
        // base64编码的私钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(decoded));
        // RSA解密
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        String outStr = new String(cipher.doFinal(inputByte));
        return outStr;
    }

    /**
     * RSA 公钥加密,【限制长度】
     *
     * @param str       加密字符串
     * @param publicKey 公钥
     * @return 密文
     */
    public static String encryptByPublicKey(String str, String publicKey) throws Exception {
        // base64编码的公钥
        byte[] keyBytes = decryptBASE64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(keyBytes));
        // RSA加密
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);

        byte[] data = str.getBytes("UTF-8");
        // 加密时超过117字节就报错。为此采用分段加密的办法来加密
        byte[] enBytes = null;
        for (int i = 0; i < data.length; i += MAX_ENCRYPT_BLOCK) {
            // 注意要使用2的倍数,否则会出现加密后的内容再解密时为乱码
            byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + MAX_ENCRYPT_BLOCK));
            enBytes = ArrayUtils.addAll(enBytes, doFinal);
        }
        String outStr = encryptBASE64(enBytes);
        return outStr;
    }

    /**
     * RSA 私钥解密,【限制长度】
     *
     * @param encryStr   加密字符串
     * @param privateKey 私钥
     * @return 明文
     */
    public static String decryptByPrivateKey(String encryStr, String privateKey) throws Exception {
        // base64编码的私钥
        byte[] decoded = decryptBASE64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(decoded));
        // RSA解密
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, priKey);

        // 64位解码加密后的字符串
        byte[] data = decryptBASE64(encryStr);
        // 解密时超过128字节报错。为此采用分段解密的办法来解密
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.length; i += MAX_DECRYPT_BLOCK) {
            byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + MAX_DECRYPT_BLOCK));
            sb.append(new String(doFinal));
        }
        return sb.toString();
    }

    /**
     * BASE64Encoder 加密
     *
     * @param data 要加密的数据
     * @return 加密后的字符串
     */
    private static String encryptBASE64(byte[] data) {
        return new String(Base64.encodeBase64(data));
    }

    /**
     * BASE64Encoder 解密
     *
     * @param data 要解密的数据
     * @return 解密后的字节
     */
    private static byte[] decryptBASE64(String data) {
        return Base64.decodeBase64(data);
    }

    // - - - - - - - - - - - - - - - - - - - - SIGN 签名,验签 - - - - - - - - - - - - - - - - - - - - //

    /**
     * 加签:生成报文签名
     *
     * @param content    报文内容
     * @param privateKey 私钥
     * @param encode     编码
     * @return
     */
    public static String doSign(String content, String privateKey, String encode) {
        try {
            String unsign = Base64.encodeBase64String(content.getBytes(StandardCharsets.UTF_8));
            byte[] privateKeys = Base64.decodeBase64(privateKey.getBytes());
            PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeys);
            KeyFactory mykeyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PrivateKey psbcPrivateKey = mykeyFactory.generatePrivate(privateKeySpec);
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initSign(psbcPrivateKey);
            signature.update(unsign.getBytes(encode));
            byte[] signed = signature.sign();
            return Base64.encodeBase64String(signed);
        } catch (Exception e) {
            logger.error("生成报文签名出现异常");
        }
        return null;
    }

    /**
     * 验证:验证签名信息
     *
     * @param content   签名报文
     * @param signed    签名信息
     * @param publicKey 公钥
     * @param encode    编码格式
     * @return
     */
    public static boolean doCheck(String content, String signed, PublicKey publicKey, String encode) {
        try {
            // 解密之前先把content明文,进行base64转码
            String unsigned = Base64.encodeBase64String(content.getBytes(encode));
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initVerify(publicKey);
            signature.update(unsigned.getBytes(encode));
            boolean bverify = signature.verify(Base64.decodeBase64(signed));
            return bverify;
        } catch (Exception e) {
            logger.error("报文验证签名出现异常");
        }
        return false;
    }
}
  1. 测试类
package com.fandf.demo.encrypt;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;

/**
 * @author fandongfeng
 */
public class Test {

    public static void main(String[] args) {
        String sendMesg = "天王盖地虎,小鸡炖蘑菇";
        System.out.println("需要加密传输的数据(sendMesg)为:" + sendMesg);
        // 用于封装 RSA 随机产生的公钥与私钥
        Map<Integer, String> keyMap = new HashMap<Integer, String>();

        /** AES:随机生成加密秘钥 */
        KeyGenerator keyGen = null;
        try {
            keyGen = KeyGenerator.getInstance("AES");
            keyGen.init(128);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        SecretKey key = keyGen.generateKey();
        String AESKeyStr = Base64.encodeBase64String(key.getEncoded());

        System.out.println("随机生成的AES加密秘钥(AESKeyStr)为:" + AESKeyStr);

        /** RSA:生成公钥和私钥 */
        KeyPairGenerator keyPairGen = null;
        try {
            keyPairGen = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        // 初始化密钥对生成器,指定位数,不指定种子
        keyPairGen.initialize(2048, new SecureRandom());

        // 生成一个密钥对,保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        // 得到 RSA 私钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        // 得到 RSA 公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

        // 得到公钥字符串
        String publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded()));
        System.out.println("随机生成的公钥(publicKey)为:" + publicKeyStr);
        // 得到私钥字符串
        String privateKeyStr = new String(Base64.encodeBase64((privateKey.getEncoded())));
        System.out.println("随机生成的私钥(privateKey)为:" + privateKeyStr);

        // 1.客户端:AES秘钥key加密数据
        String encryptData = AESUtil.encrypt(AESKeyStr, sendMesg, "UTF-8");
        System.out.println("AES秘钥key加密后的字符串为:" + encryptData);
        // 2.客户端:RSA公钥加密AES秘钥key(keyEn)
        String encryptKey = null;
        try {
            encryptKey = RSAUtil.encrypt(AESKeyStr, publicKeyStr);
            System.out.println("RSA加密后的AES秘钥key为:" + encryptKey);
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("==============================客户端 将AES秘钥key加密后的数据  和  RSA加密后的AES秘钥 发送给服务端");

        System.out.println("============================== 服务端收到数据,开始工作");
        // 3.服务端:RSA私钥解密AES秘钥key(keyEn)
        String aeskey = null;
        try {
            aeskey = RSAUtil.decrypt(encryptKey, privateKeyStr);
            System.out.println("服务端,RSA解密后的AES秘钥key为:" + aeskey);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 4.服务端:AES秘钥key解密数据
        String data = AESUtil.decrypt(aeskey, encryptData, "UTF-8");
        System.out.println("服务端,AES秘钥key解密后的字符串为:" + data);
    }

}

打印输出结果

需要加密传输的数据(sendMesg)为:天王盖地虎,小鸡炖蘑菇
随机生成的AES加密秘钥(AESKeyStr)为:8SPp19W8g/sZ6jpP8r89cg==
随机生成的公钥(publicKey)为:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoRgrQGG0MwxebDpHLhGhcdBM1HS0Z+8DYE8zXsU9Y0IWPou2ht3qYSoJPJWDDoGvj+Rd+tjb7HyPijEpquWYocbufG7gfhn0BWrj+mR08TgS3FfmIRHkGAlNKcZmEqe670SjMlkMIlILye7dT3jdjcP1kkf9IRfAtfBC7P+k40KXG3zwBGe8E/gT3xEEPM551/A6K1KYO9Ocgvb5NI1xBwMKNI+u6hZ9dqJHMlbKMtwh7S74L/rh+ROMSnZ/kX5pvyHmRhWjn7i14nTKW/eal+hYmIHA+Vpz7InEGnEP+qHjWUTFAM1F9N4gaJs8TIObSfeF2Bt+St/cFBNssCgy+QIDAQAB
随机生成的私钥(privateKey)为:MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQChGCtAYbQzDF5sOkcuEaFx0EzUdLRn7wNgTzNexT1jQhY+i7aG3ephKgk8lYMOga+P5F362NvsfI+KMSmq5Zihxu58buB+GfQFauP6ZHTxOBLcV+YhEeQYCU0pxmYSp7rvRKMyWQwiUgvJ7t1PeN2Nw/WSR/0hF8C18ELs/6TjQpcbfPAEZ7wT+BPfEQQ8znnX8DorUpg705yC9vk0jXEHAwo0j67qFn12okcyVsoy3CHtLvgv+uH5E4xKdn+Rfmm/IeZGFaOfuLXidMpb95qX6FiYgcD5WnPsicQacQ/6oeNZRMUAzUX03iBomzxMg5tJ94XYG35K39wUE2ywKDL5AgMBAAECggEBAIVE4lsjuRjWLbMpT0OMcFwgr76/QZQOBmQBgYTwdYWM4awilwDhy4lQZk3Jfp9cqCnJCfqAtwfgUDtJyqfHw0pqsVcdvvhzbg2hTTMTMi9wbSH+UbKgA2vjHgPmTwE1448X4E7BnikyaPBIfKvHWLp0F89JYN6ksNeTCTrZjsY2OwrvCurcLYPZncVXJxk3cp09kd+66MFtmeoAWKrv5IyheqAV9j62md3fRBJRyMEnmawje0HaP0k5AiyuAOedunolcA5EUyT5Drunnb2xLdhFBheMRflL2bEMzkOK3rdCMvdJlpqe/ojrohiyWi6iiC3KmzBnbiLNH6m0/MSS89ECgYEA10CEYlIMyMUi2cIPi6s116lDHyj9P4G93uqaL5TGLJrK/y5aQyI/uR1h4TnpjsKYUgiR4vb1N86uSHt8tAC45U3laVkvmEgZAWJT9GoSWzuyDtAfzETbzkAQuWFWM7V/DW5Utj0YUu1OOZG+owj47zBk8shWdlcbfIUs/paGxL0CgYEAv5cUuWlJFhHHpO8cTEgTZAucin9/vbR6fyuqiaqd7j5JEsF+qKVN/lpyDrH7vBfA8vtQrGSq8dvS8LAgq+OUMrRVPkYO1DgO0a6wHahat8DxLvcTD+jAV1XauWwLiX3++QWSEkkyofA2Uf5WmapNhrnAAxmAxUoKvomOhdCdUO0CgYAXl5Oq7xFFpA24zkND7KT/GScpMCXpov+7gf0aP/UkiGa9Z0gvWX6gfG7w75cAtaVaQGQ0+xpPXpDNkvNNC1M4lrwROtwzlZtgAnXvMP0IENfoNbl2ewmYZn8uwlNfYYImZ7RTMQkMdcQAHVBGsEIQfT5jOb/4Qn3ZvQL8eGUXBQKBgQCNvlLA0doWj9Tqe1SuQuzFqamI9ccmLK4sA7xJ2Ya6Si55x9nTH2lScsvLf3ZEtDY2DiSjRl8KTJ4FH+ksAlUUJkKireYur8KW8uytJG7pX7+QBY9+x631bzlA0WS/tg27YpmtGaZyFGu7wbWEPnDY6ffa0zVnwN2uFcrxyWN6CQKBgQCD/N3m0JB0TjSC/PRrBkiyiHACvmFRQW2z5YzOJpJI839XdEDX0AHWbGLkgNmr+fJf+p+tSOuxQSzreQNMcHNexvvfLnYwstKuIc16w8hR9D0payxosh78vLDihbql5RMEhyUUhnyU24ll++qR6nChSTFDPFJXaaDgtUGJ0EF7ag==
AES秘钥key加密后的字符串为:e7xA6cCYjSg+aYq5LyCIdwghUyLocH7hvaHuR3T6laIkf4+5LXF80Ectj6YSXrOd
RSA加密后的AES秘钥key为:BLF+Flz5CoNKOCUfOK9BD6b7fY8jHkm97gR+v34kCjiPyPW1bY6p2pWB3H1h37O2vUyrXlfOUuNQUKZomj/nng4ggmkCmZ49gdDRkSo/3D+ycXy4tU16r3hTWIoXQxtE9oKOy7QO6aIvYT6jjnq6ULzCU+iZ0mB541GMlkU2WFnIiDIK0T+45H2exlv4NJcT7sW9Lmy6L43l/aW+gfSW65ud+7ixfP2/ST7NfTt+6zIGQD1198Pqx1woUg6lK4FY0MXKz9NTUxWJcHoOs+aPREQABsHRgyjM2WFIYD34h7TZVSrmCP7XCJoENFpZyaqjahjX/LJBbmOfMDHxg00PLA==
==============================客户端 将AES秘钥key加密后的数据  和  RSA加密后的AES秘钥 发送给服务端
============================== 服务端收到数据,开始工作
服务端,RSA解密后的AES秘钥key为:8SPp19W8g/sZ6jpP8r89cg==
服务端,AES秘钥key解密后的字符串为:天王盖地虎,小鸡炖蘑菇

  • 9
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!下面是一个使用RSAAES混合加密的示例代码: ```python from Crypto.Cipher import AES, PKCS1_OAEP from Crypto.PublicKey import RSA from Crypto.Random import get_random_bytes # 生成RSA密钥对 key = RSA.generate(2048) private_key = key.export_key() public_key = key.publickey().export_key() # 加密数据 data = b'This is a secret message.' # 使用AES生成随机密钥 session_key = get_random_bytes(16) # 使用RSA公钥加密AES密钥 rsa_cipher = PKCS1_OAEP.new(RSA.import_key(public_key)) encrypted_session_key = rsa_cipher.encrypt(session_key) # 使用AES加密数据 aes_cipher = AES.new(session_key, AES.MODE_EAX) ciphertext, tag = aes_cipher.encrypt_and_digest(data) # 传输加密后的数据和密钥... # 接收方解密数据 # 使用RSA私钥解密AES密钥 rsa_cipher = PKCS1_OAEP.new(RSA.import_key(private_key)) session_key = rsa_cipher.decrypt(encrypted_session_key) # 使用AES解密数据 aes_cipher = AES.new(session_key, AES.MODE_EAX) decrypted_data = aes_cipher.decrypt_and_verify(ciphertext, tag) print(decrypted_data.decode()) ``` 在这个示例中,首先生成了一个RSA密钥对。然后,生成了一个随机的AES密钥,并使用RSA公钥加密了该密钥。接下来,使用AES密钥对要加密数据进行加密,并生成了一个认证标签。最后,发送加密后的数据加密AES密钥给接收方。 接收方使用RSA私钥解密接收到的AES密钥,并使用解密后的AES密钥解密数据,并进行认证。 请注意,这只是一个简单的示例代码,用于演示RSAAES混合加密的基本概念。在实际应用中,需要更多的安全措施和错误处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值