RSA+AES加解密

这篇具有很好参考价值的文章主要介绍了RSA+AES加解密。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

需求&实现思路

工作中遇到一个需求,需要将接口数据加密发送给后台,项目中采用RSA+AES方式,记录一下思路和实现。

一、加密
1、随机生成AES 32位密钥
2、通过AES对传递数据加密
3、通过RSA的公钥Publickey对AES的密钥进行加密
4、通过RSA的私钥Privatekey对数据进行签名

二、解密
1、得到数据拿到sign值,先做验签
2、使用RSA的私钥private_key解密拿到AES的aesKey
3、使用AES解密得到所需数据

下面是具体实现步骤
1、通过opensll生成加解密所需要的公钥和私钥,生成步骤自行百度,这里 不在介绍
2、AES加解密

    public static class AESUtils {
        private static final String AES = "AES";
        //偏移量
        private static final String IV_STRING = "";
        /**
         * 密钥长度32字节,256位
         */
        private static final int AES_KEY_LENGTH = 32;

        /**
         * 随机生成32位AES密钥
         */
        public static String getRandomString() {
        	//生成规则自己定义
            String base = "";
            Random random = new Random();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < AES_KEY_LENGTH; i++) {
                int number = random.nextInt(base.length());
                sb.append(base.charAt(number));
            }
            return sb.toString();
        }

        /**
         * 加密
         *
         * @param content 加密内容
         * @return 密文
         * @throws Exception e
         */
        @RequiresApi(api = Build.VERSION_CODES.O)
        public static String encrypt(String key, String content) throws Exception {
            byte[] encryptedBytes = new byte[0];
            try {
                byte[] byteContent = content.getBytes();
                // 注意,为了能与 iOS 统一
                // 这里的 key 不可以使用 KeyGenerator、SecureRandom、SecretKey 生成
                byte[] enCodeFormat = key.getBytes(StandardCharsets.UTF_8);
                SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, AES);
                byte[] initParam = IV_STRING.getBytes();
                IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
                // 指定加密的算法、工作模式和填充方式
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
                encryptedBytes = cipher.doFinal(byteContent);
                // 同样对加密后数据进行 base64 编码
            } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
                LogUtil.e("AES decrypt Exception,content = {},Exception = {}" + content + Arrays.toString(e.getStackTrace()));

            }


//            return Base64.getUrlEncoder().encodeToString(encryptedBytes);
            return Base64Util.encode(encryptedBytes);
        }

        /**
         * 解密
         *
         * @param content 密文
         * @return 明文
         * @throws Exception e
         */
        @RequiresApi(api = Build.VERSION_CODES.O)
        public static String decrypt(String content, String aesKey) {
            // base64 解码
            try {
                byte[] encryptedBytes = Base64Util.decode(content);
                byte[] enCodeFormat = aesKey.getBytes();
                SecretKeySpec secretKey = new SecretKeySpec(enCodeFormat, AES);
                byte[] initParam = IV_STRING.getBytes();
                IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
                byte[] result = cipher.doFinal(encryptedBytes);
                return new String(result, "UTF-8");
            } catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {

                LogUtil.e("AES decrypt Exception,content = {},Exception = {}" + content + Arrays.toString(e.getStackTrace()));
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

    }

2、RSA加解密,opensll生成公钥和私钥的pem文件放在项目assets下

    public static class RSAUtils {
        /**
         * 算法名字
         */
        private static final String RSA_ALGORITHM = "RSA";

        /**
         * 消息摘要算法
         */
        private static final String MD_ALGORITHM = "SHA256withRSA";

        /**
         * RSA最大加密明文大小
         */
        private static final int MAX_ENCRYPT_BLOCK = 117;

        /**
         * RSA最大解密密文大小
         */
        private static final int MAX_DECRYPT_BLOCK = 128;

        /**
         * 制作公钥
         *
         * @return
         */
        @RequiresApi(api = Build.VERSION_CODES.O)
        public static PublicKey getPublicKey() {

            PublicKey public_Key = null;
            try {
                assert MyApplication.instance != null;
                InputStream in = MyApplication.instance.getResources().getAssets().open("public_key.pem");
                BufferedReader br = new BufferedReader(new InputStreamReader(in));
                String readLine = null;
                StringBuilder sb = new StringBuilder();
                while ((readLine = br.readLine()) != null) {
                    if (readLine.charAt(0) == '-') {
                        continue;
                    } else {
                        sb.append(readLine);
                    }
                }
                KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
                byte[] buffer = Base64Util.decode(sb.toString());
                EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
                public_Key = keyFactory.generatePublic(keySpec);
                return public_Key;
            } catch (Exception e) {
            }
            return null;
        }
       
        /**
         * 制作私钥
         *
         * @return
         */
        @RequiresApi(api = Build.VERSION_CODES.O)
        public static PrivateKey getPrivateKey() {

            PrivateKey privateKey = null;
            try {
                assert MyApplication.instance != null;
                InputStream in = MyApplication.instance.getResources().getAssets().open("private_key.pem");
                BufferedReader br = new BufferedReader(new InputStreamReader(in));
                String readLine = null;
                StringBuilder sb = new StringBuilder();
                while ((readLine = br.readLine()) != null) {
                    if (readLine.charAt(0) == '-') {
                        continue;
                    } else {
                        sb.append(readLine);
                    }
                }
                in.close();
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                byte[] buffer = Base64Util.decode(sb.toString());
                EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(buffer);
                privateKey = keyFactory.generatePrivate(privateKeySpec);
                return privateKey;

            } catch (Exception e) {
            }
            return null;
        }


        /**
         * RSA加密
         * <p>
         * //         * @param data      待加密数据
         *
         * @param publicKey 公钥
         * @return
         */
        @RequiresApi(api = Build.VERSION_CODES.O)
        public static String encrypt(String aesKey, PublicKey publicKey) {
            //RSA加密
            try {
                if (publicKey == null) {
                    return null;
                }
                Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
                int inputLen = aesKey.getBytes().length;
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                int offset = 0;
                byte[] cache;
                int i = 0;
                // 对数据分段加密
                while (inputLen - offset > 0) {
                    if (inputLen - offset > MAX_ENCRYPT_BLOCK) {
                        cache = cipher.doFinal(aesKey.getBytes(), offset, MAX_ENCRYPT_BLOCK);
                    } else {
                        cache = cipher.doFinal(aesKey.getBytes(), offset, inputLen - offset);
                    }
                    out.write(cache, 0, cache.length);
                    i++;
                    offset = i * MAX_ENCRYPT_BLOCK;
                }
                byte[] encryptedData = out.toByteArray();
                out.close();
                // 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串
                // 加密后的字符串
                return Base64Util.encode(encryptedData);
            } catch (Exception e) {
//                log.warn("encrypt error, ex:{}", e.getMessage());
            }
            return null;
        }

        /**
         * RSA解密
         *
         * @param data       待解密数据
         * @param privateKey 私钥
         * @return
         */
        @RequiresApi(api = Build.VERSION_CODES.O)
        public static String decrypt(String data, PrivateKey privateKey) {
            try {
                if (privateKey == null) {
                    return null;
                }
                Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                byte[] dataBytes = Base64Util.decode(data);
                int inputLen = dataBytes.length;
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                int offset = 0;
                byte[] cache;
                int i = 0;
                // 对数据分段解密
                while (inputLen - offset > 0) {
                    if (inputLen - offset > MAX_DECRYPT_BLOCK) {
                        cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
                    } else {
                        cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
                    }
                    out.write(cache, 0, cache.length);
                    i++;
                    offset = i * MAX_DECRYPT_BLOCK;
                }
                out.close();
                // 解密后的内容
                return out.toString("UTF-8");
            } catch (Exception e) {
//                log.warn("decrypt error, ex:{}", e.getMessage());
            }
            return null;
        }

        /**
         * 签名
         *
         * @param data       待签名数据
         * @param privateKey 私钥
         * @return 签名
         */
        @RequiresApi(api = Build.VERSION_CODES.O)
        public static String sign(String data, PrivateKey privateKey) {
            try {
                byte[] keyBytes = privateKey.getEncoded();
                PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
                KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
                PrivateKey key = keyFactory.generatePrivate(keySpec);
                Signature signature = Signature.getInstance(MD_ALGORITHM);
                signature.initSign(key);
                signature.update(data.getBytes());
                return Base64Util.encode(signature.sign());
            } catch (Exception e) {
//                log.warn("RSA sign error, ex:{}", e.getMessage());
            }
            return null;
        }

        /**
         * 验签
         *
         * @param srcData   原始字符串
         * @param publicKey 公钥
         * @param sign      签名
         * @return 是否验签通过
         */
        @RequiresApi(api = Build.VERSION_CODES.O)
        public static boolean verify(String srcData, PublicKey publicKey, String sign) {
            try {
                byte[] keyBytes = publicKey.getEncoded();
                X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
                KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
                PublicKey key = keyFactory.generatePublic(keySpec);
                Signature signature = Signature.getInstance(MD_ALGORITHM);
                signature.initVerify(key);
                signature.update(srcData.getBytes());
                return signature.verify(Base64Util.decode(sign));
            } catch (Exception e) {
            }
            return false;
        }

    }

3、Base64Util编解码工具类 ,需要依赖javabase64-1.3.1.jar

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import it.sauronsoftware.base64.Base64;

public class Base64Util {
    /** */
    /**
     * 文件读取缓冲区大小
     */
    private static final int CACHE_SIZE = 1024;

    /** */
    /**
     * <p>
     * BASE64字符串解码为二进制数据
     * </p>
     *
     * @param base64
     * @return
     * @throws Exception
     */
    public static byte[] decode(String base64) throws Exception {
        return Base64.decode(base64.getBytes());
    }

    /** */
    /**
     * <p>
     * 二进制数据编码为BASE64字符串
     * </p>
     *
     * @param bytes
     * @return
     * @throws Exception
     */
    public static String encode(byte[] bytes) throws Exception {
        return new String(Base64.encode(bytes));
    }

    /** */
    /**
     * <p>
     * 将文件编码为BASE64字符串
     * </p>
     * <p>
     * 大文件慎用,可能会导致内存溢出
     * </p>
     *
     * @param filePath
     *            文件绝对路径
     * @return
     * @throws Exception
     */
    public static String encodeFile(String filePath) throws Exception {
        byte[] bytes = fileToByte(filePath);
        return encode(bytes);
    }

    /** */
    /**
     * <p>
     * BASE64字符串转回文件
     * </p>
     *
     * @param filePath
     *            文件绝对路径
     * @param base64
     *            编码字符串
     * @throws Exception
     */
    public static void decodeToFile(String filePath, String base64)
            throws Exception {
        byte[] bytes = decode(base64);
        byteArrayToFile(bytes, filePath);
    }

    /** */
    /**
     * <p>
     * 文件转换为二进制数组
     * </p>
     *
     * @param filePath
     *            文件路径
     * @return
     * @throws Exception
     */
    public static byte[] fileToByte(String filePath) throws Exception {
        byte[] data = new byte[0];
        File file = new File(filePath);
        if (file.exists()) {
            FileInputStream in = new FileInputStream(file);
            ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
            byte[] cache = new byte[CACHE_SIZE];
            int nRead = 0;
            while ((nRead = in.read(cache)) != -1) {
                out.write(cache, 0, nRead);
                out.flush();
            }
            out.close();
            in.close();
            data = out.toByteArray();
        }
        return data;
    }

    /** */
    /**
     * <p>
     * 二进制数据写文件
     * </p>
     *
     * @param bytes
     *            二进制数据
     * @param filePath
     *            文件生成目录
     */
    public static void byteArrayToFile(byte[] bytes, String filePath)
            throws Exception {
        InputStream in = new ByteArrayInputStream(bytes);
        File destFile = new File(filePath);
        if (!destFile.getParentFile().exists()) {
            destFile.getParentFile().mkdirs();
        }
        destFile.createNewFile();
        OutputStream out = new FileOutputStream(destFile);
        byte[] cache = new byte[CACHE_SIZE];
        int nRead = 0;
        while ((nRead = in.read(cache)) != -1) {
            out.write(cache, 0, nRead);
            out.flush();
        }
        out.close();
        in.close();
    }

}

4、下面是项目中世界运用文章来源地址https://www.toymoban.com/news/detail-439014.html

			一、加密
			
 			//获取AES签名
            val aesKey = CipherUtils.AESUtils.getRandomString()
            //加密数据
            val data = CipherUtils.AESUtils.encrypt(aesKey, "需要加密的数据")
            //RSA加密
            val key = CipherUtils.RSAUtils.encrypt(aesKey, publicKey)
            //RSA签名
            val sign = CipherUtils.RSAUtils.sign(data, privateKey)
				二、解密
				//RSA解密
                val aesKey = CipherUtils.RSAUtils.decrypt("后台返回的AES的key值", privateKey)
                //AES解密
                val data = CipherUtils.AESUtils.decrypt("后台返回的加密数据", aesKey)

到了这里,关于RSA+AES加解密的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RSA+AES实现混合加密

    为什么使用RSA + AES混合加密 1.加密介绍 RSA加密: 属于非对称加密,公钥用于对数据进行加密,私钥对数据进行解密,两者不可逆。公钥和私钥是同时生成的,且一一对应。比如:客户端拥有公钥,服务端拥有公钥和私钥。客户端将数据通过公钥进行加密后,发送密文给服务端

    2024年02月05日
    浏览(50)
  • 用java语言写一个AES算法,使用AES(CBC模式)对数据进行加密或解密。加解密用到的密钥(Key)和密钥偏移量(IV),代码实例类编写。

    以下是一个使用Java编写的AES算法实例,使用AES(CBC模式)对数据进行加密和解密。代码中包括了生成随机密钥和密钥偏移量的方法。 java Copy code import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidAlgorithmParameterException; import

    2024年02月07日
    浏览(63)
  • C# 实现对称加密算法(AES)与非对称加密算法(RSA),包含前端加密对应算法实现

    一种既简单速度又快的加密方式,加密与解密使用的都是同一个密钥,别名又叫做:单密钥加密;对称加密有很多公开算法,并且因为它效率很高,所以适用于加密大量数据的场合;但其密钥的传输过程是不安全的,并且容易被破解,密钥管理起来也相对麻烦。 需要两个密钥

    2024年02月09日
    浏览(68)
  • AES加密解密python实现

            关于现代密码学算法,可以查看以下博客全面了解 CISSP考试要求里的“应用密码学”内容辅助记忆趣味串讲_晓翔仔的博客-CSDN博客         AES的细节知识,可以查阅 AES加密算法的详细介绍与实现_TimeShatter的博客-CSDN博客          AES 加密最常用的模式就是

    2024年02月05日
    浏览(79)
  • Java实现RSA加解密

    2024年02月15日
    浏览(36)
  • Java 实现 AES 加密和解密完整示例

    AES,全称为 Advanced Encryption Standard,是一种分组密码算法,用于保护敏感数据的传输和存储。AES 分为 128 位和 256 位两种密钥长度,可以对数据进行加密和解密,保证数据的安全性和完整性。AES 主要应用于电子商务、移动支付、网络安全等领域,被广泛运用于现代社会的各个

    2024年02月04日
    浏览(67)
  • RSA加解密算法的简单实现

    就前不久完成的RSA加解密实现这一实验来水一篇文章 算法原理: 一.米勒拉宾素性检测算法 米勒-拉宾(MillerRabbin)素性测试算法是一个高效判断素数的方法。 其涉及到的原理如下:         1、费马小定理: 如果 p 为质数             (在 mod p 的情况下 )         2、

    2024年02月05日
    浏览(33)
  • RSA 加密解密算法实现(简单,易懂)!!!

    目录 一、什么是RSA算法 1.对称加密 2.非对称加密 3.非对称加密的应用 二、RSA算法的基础操作步骤 1.生成公钥和私钥 2.用公钥加密信息  3.用私钥解密信息 三、AC代码 六、RSA算法的测试  七、共勉     在计算机中常用的加密算法分为两类: 对称加密算法和非对称加密算法。

    2024年01月20日
    浏览(68)
  • RSA 公私钥加解密Java实现

    1.简单快速集成,饮用hutool工具包实现 1)引入hutool包 2) 制作好自己的rsa公私钥文件,通过openssl实现即可,直接放到resources下面  3)读取rsa文件,进行加解密实现,公钥加密,私钥解密,注意点都在里面注释了。 2.不借助工具,直接引用java security包实现功能 1)公私钥依然

    2024年02月10日
    浏览(41)
  • SpringCloud-Gateway实现RSA加解密

    Gateway网关作为流量的入口,有的接口可能需要对请求内容加密,返回结果加密,保证数据安全性。 一、RSA介绍         RSA主要使用大整数分解这个数学难题进行设计,巧妙地利用了数论的概念。给了RSA公钥,首先想到的攻击就是分解模数,给了的因子攻击者可以计算得到

    2024年02月16日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包