企业级项目通讯常用的加密方式 AES+RSA (可直接拷到项目中使用)

本文详细介绍了AES和RSA两种加密算法,AES是对称加密,适用于大量数据快速加密,RSA是非对称加密,适用于安全传输公钥。通过Java代码示例展示了AES和RSA的加密解密过程,并探讨了AES与RSA结合使用以提高安全性的方式。
摘要由CSDN通过智能技术生成

简单解释下AES和RSA
AES:对称加密,双方用一样的秘钥加密解密,耗时根据加密长度线性增长.

RSA:非对称加密,有公钥和私钥,用公钥加密,用私钥解密,一般用在单向请求的业务中.发送方只保存公钥,用来加密原文.接收方只保存私钥,用来解密密文.耗时根据加密长度指数性增长.

直接上代码;
AES 工具类

public class AESUtil {
    private static final String AES = "AES";
    private static final String UTF8="utf-8";

    /**
     * 生成秘钥
     * @param size 长度
     * @param secure 加密参数
     * @return 秘钥
     */
    public static String getAESKey(int size,String secure) throws NoSuchAlgorithmException {
        KeyGenerator kgen = KeyGenerator.getInstance(AES);

        /**可以根据参数生成固定的秘钥*/
        if (null == secure || secure.equals("")){
            kgen.init(size, new SecureRandom());
        }else{
            kgen.init(size, new SecureRandom(secure.getBytes()));
        }

        /**生成秘钥并转base64编码*/
        SecretKey secretKey = kgen.generateKey();
        byte[] enCodeFormat = secretKey.getEncoded();
        String encodeKey = Base64.getEncoder().encodeToString(enCodeFormat);
        System.out.println("AES秘钥::"+encodeKey);
        return encodeKey;
    }

    /**
     * AES 加密
     * @param content 原文
     * @param aesKey  秘钥
     * @return 密文
     * @throws Exception
     */
    public static String encrypt(String content, String aesKey) throws Exception {
        /**base64解码秘钥 并转换为AES专用密钥*/
        SecretKeySpec key = new SecretKeySpec(Base64.getDecoder().decode(aesKey), AES);
        Cipher cipher = Cipher.getInstance(AES);
        byte[] byteContent = content.getBytes(UTF8);
        /**初始化为加密模式的密码器 */
        cipher.init(Cipher.ENCRYPT_MODE, key);
        /**加密并转出base64返回密文*/
        byte[] result = cipher.doFinal(byteContent);
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * AES 解码
     * @param content 密文
     * @param aesKey 秘钥
     * @return 原文
     */
    public static String decrypt(String content, String aesKey) throws Exception {
        /**将秘钥,密文 base64字节*/
        byte[] decodeKey = Base64.getDecoder().decode(aesKey);
        byte[] decodeContent = Base64.getDecoder().decode(content);
        /**转换为AES专用密钥*/
        SecretKeySpec key = new SecretKeySpec(decodeKey, AES);
        /**创建 初始化 容器*/
        Cipher cipher = Cipher.getInstance(AES);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] result = cipher.doFinal(decodeContent);
        /**返回明文*/
        return new String(result,UTF8);
    }

    public static void main(String[] args) {
        try {
            getAESKey(128,null);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

注:可以根据传入的一样的参数从而生成一样的秘钥

AES 测试

public class AESTest {
    public static final String AES_KEY = "+6x5a6mr033+USKVCpWxog==";

    public static void main(String[] args) {
        String content = "小桥流水人家";

        try {
            String encrypt = AESUtil.encrypt(content, AES_KEY);
            System.out.println("密文::"+encrypt);

            String decrypt = AESUtil.decrypt(encrypt, AES_KEY);
            System.out.println("原文::"+decrypt);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出内容:

密文::b2xklTIno1Q0eAOXgvG8noriNuQR4wUrf7QkZdaIdI4=
原文::小桥流水人家

RSA工具类

public class RSAUtil {
    private static final String RSA = "RSA";
    private static final String UTF8="utf-8";
    /**
     * 生成秘钥对
     * @param size 密钥长度 于原文长度对应 以及越长速度越慢
     * @param secure 用于生成秘钥的参数
     * @throws NoSuchAlgorithmException
     */
    public static void genKeyPair(int size,String secure) throws NoSuchAlgorithmException {
        /**基于RSA算法生成公钥和私钥对对象*/
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(RSA);

        /**可以根据参数生成固定的秘钥*/
        if (null == secure || secure.equals("")){
            keyPairGen.initialize(size, new SecureRandom());
        }else {
            keyPairGen.initialize(size, new SecureRandom(secure.getBytes()));
        }
        /**生成一个密钥对*/
        KeyPair keyPair = keyPairGen.generateKeyPair();
        /**得到私钥 并用base64加密*/
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());
        System.out.println("秘钥::"+privateKeyString);
        System.out.println("私钥长度::"+privateKeyString.length());

        /**得到公钥 并用base64加密*/
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
        System.out.println("公钥::"+publicKeyString);
        System.out.println("公钥长度::"+publicKeyString.length());
    }

    /**
     * 公钥加密
     * @param str 加密内容
     * @param publicKey 公钥
     * @return
     * @throws Exception
     */
    public static String encrypt(String str, String publicKey) throws Exception {
        /**base64解码公钥*/
        byte[] decoded = Base64.getDecoder().decode(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(RSA).generatePublic(new X509EncodedKeySpec(decoded));
        /**RSA加密*/
        Cipher cipher = Cipher.getInstance(RSA);
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        byte[] content = cipher.doFinal(str.getBytes(UTF8));
        /**base64将字节转字符*/
        String outStr = Base64.getEncoder().encodeToString(content);
        return outStr;
    }

    /**
     * 私钥解密
     * @param str 密文
     * @param privateKey  私钥
     * @return
     * @throws Exception
     */
    public static String decrypt(String str, String privateKey) throws Exception {
        /**base64把密文转称字节*/
        byte[] inputByte = Base64.getDecoder().decode(str);
        /**base64解码私钥*/
        byte[] decoded = Base64.getDecoder().decode(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
        /**RSA解密*/
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        String outStr = new String(cipher.doFinal(inputByte));
        return outStr;
    }

    public static void main(String[] args) {
        try {
            genKeyPair(2048,null);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

注:跟AES一样可以传入一样的参数获得一样的秘钥对

AES 测试

public class RSATest {
    /**公钥 用于加密*/
    public static final String PRIVATE_KEY= "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCEHt3BzouSNGIY/mxMBOF5oH/LYAo6dunHitMD4zv8wYN6AI3/tZp69uAW3bcrPWN3bGGEQj3uTRLP5SwqTn5b3KIYAWU1oShscHmtTcohQV0w4AH9eGAaZcY6gXYVckW7Y0EGYKPDWf5JRrB6AFcUV1vIx4pTWaecuDNzwzqkUNUjj05KiEHZsPuS4YUXP7z+Oi4i0RKnh0Mp4bbZC4BcJ1x/420t8YFzJnIt+E6jN3glxBaaSKluYjLxmz4gdxxeHXoaLBuWccshV6FCuuMJigoO4DSKQiPRIn88XrV9aebLCjfm3qCBlaaTO5CQvqtQsrxgUqmVLQ6M/D0lGEDPAgMBAAECggEAGxpJ22wHbaKZTQ9EIAQQTOcD0DCPaJbkNi7gQrfmol8AHZLnjkEuw3LJXWd2H8SkFueAyaTdF3lwFn2opbUcbrO//LSskmfQ5w3bqBWBFXlXKKOLRPfgnwmptG7CTnv2mg4uVKSWc4iOhXGe2igftOiGx5VHZvnJTHjs9R5jdTlkGADB26z4P1KRs0nhqCBjVXL9if6T6eLV+fJfS/SUynxSVbbsQ3XGaZnfzKU6PgUxnrndD5yfl0JPb31v0p1lpZ47lYFRbsOPKXbbheJtIrTaNcoJjor6udHSa4QFv8dOJO1j/oZvQcD+HXW69f6F1gin7/kV0MJRFZ1UQloXAQKBgQDF1IBJOwhLeHSrdTwHylnnrr1MBhsdBERJqbldt0h9RNjVeqgBmxnC5W0olxdDcaT7mC6j0E5SWSz0DfXJBSQKTFU2sy3VyWI6PsP8AymUQ976Z/6FAiJ7s/AbDECnsXkP/TrxxV7iHYLeG8CNP9bF7V1UvTaZ6pAT8LiAsW9IIQKBgQCq+CKPOIAdwMXGv/fPEP2vHY28UG0u1LflEp8lch8CMd49jk9qKD7DhDKFGsg79JKRzi8VOhCYqmJwIrJXx/lDhWhE2sBK05ekItLsEfttmTl6PIvu5G3H3F4bbBdTuPR1YYIFscpuLsBLu7rVZGBlkV4gaIRghYRXddR+1o6q7wKBgAPW9AZ31tlgJSOOyvN7wfL1OUdYdv5BLvIfETH4dLe5tluuXcRqNj3KJiw7goAUnJclhQI48Mw4Xt79xl94chKhGKZPI/yaRAXNYhBqH0x5ZMKHcjEysWilPWvI+RhIIYll6Nb4dbb9y6Rz9XDIZGrDCKS0Z3LlUpaQfYRB7V8BAoGALJizMxay3I/3RwO2GU4+ThpwaUm1YTzdhyRXXQYqroDhjr77Wh6LWKa4It48kt8WCHB2+Zt+zsPLD6MNUDZ6f7Fh5GwHMr2E1ay7xhZetlT8mDUI71SoijSiW5bTcuRQ5/l6WA/rVNhfEqIydw1K09OacOuydBb/0WyL9FX1OwMCgYBfNLg3YZX4pQpcOPv22f6mDROMDi3YJvFGcM79ryPKTX6FgP4Tj7Hrf9xwm5Qd4j6AIL29Ttt+3xlo+dLm+T8b/e59Yw94h1ZliL9OCgWNzgcV90OctTECpIulJijQk835TkrJjsMe7uPUiUs50xXIWLC3KmCuU2EDgWq0YWICzw==";
    /**私钥 用于解密*/
    public static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhB7dwc6LkjRiGP5sTATheaB/y2AKOnbpx4rTA+M7/MGDegCN/7WaevbgFt23Kz1jd2xhhEI97k0Sz+UsKk5+W9yiGAFlNaEobHB5rU3KIUFdMOAB/XhgGmXGOoF2FXJFu2NBBmCjw1n+SUawegBXFFdbyMeKU1mnnLgzc8M6pFDVI49OSohB2bD7kuGFFz+8/jouItESp4dDKeG22QuAXCdcf+NtLfGBcyZyLfhOozd4JcQWmkipbmIy8Zs+IHccXh16GiwblnHLIVehQrrjCYoKDuA0ikIj0SJ/PF61fWnmywo35t6ggZWmkzuQkL6rULK8YFKplS0OjPw9JRhAzwIDAQAB";

    public static void main(String[] args) {
        String content = "古道西风瘦马";

        try {
            /**公钥加密*/
            String encrypt = RSAUtil.encrypt(content, PUBLIC_KEY);
            /**私钥解密*/
            String decrypt = RSAUtil.decrypt(encrypt, PRIVATE_KEY);
            System.out.println("解密后的原文::"+decrypt);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出结果:

解密后的原文::古道西风瘦马

AES + RSA 组合更加安全,RSA的公钥私钥保持不变,AES的秘钥每次随机生成,发送方用AES加密原文,再用公钥加密AES的秘钥,带上加密后的秘钥和密文去请求.而接受方则先用私钥解密得到AES的秘钥再对密文进行解密

public class Demo {
    /**公钥 用于加密*/
    public static final String PRIVATE_KEY= "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCEHt3BzouSNGIY/mxMBOF5oH/LYAo6dunHitMD4zv8wYN6AI3/tZp69uAW3bcrPWN3bGGEQj3uTRLP5SwqTn5b3KIYAWU1oShscHmtTcohQV0w4AH9eGAaZcY6gXYVckW7Y0EGYKPDWf5JRrB6AFcUV1vIx4pTWaecuDNzwzqkUNUjj05KiEHZsPuS4YUXP7z+Oi4i0RKnh0Mp4bbZC4BcJ1x/420t8YFzJnIt+E6jN3glxBaaSKluYjLxmz4gdxxeHXoaLBuWccshV6FCuuMJigoO4DSKQiPRIn88XrV9aebLCjfm3qCBlaaTO5CQvqtQsrxgUqmVLQ6M/D0lGEDPAgMBAAECggEAGxpJ22wHbaKZTQ9EIAQQTOcD0DCPaJbkNi7gQrfmol8AHZLnjkEuw3LJXWd2H8SkFueAyaTdF3lwFn2opbUcbrO//LSskmfQ5w3bqBWBFXlXKKOLRPfgnwmptG7CTnv2mg4uVKSWc4iOhXGe2igftOiGx5VHZvnJTHjs9R5jdTlkGADB26z4P1KRs0nhqCBjVXL9if6T6eLV+fJfS/SUynxSVbbsQ3XGaZnfzKU6PgUxnrndD5yfl0JPb31v0p1lpZ47lYFRbsOPKXbbheJtIrTaNcoJjor6udHSa4QFv8dOJO1j/oZvQcD+HXW69f6F1gin7/kV0MJRFZ1UQloXAQKBgQDF1IBJOwhLeHSrdTwHylnnrr1MBhsdBERJqbldt0h9RNjVeqgBmxnC5W0olxdDcaT7mC6j0E5SWSz0DfXJBSQKTFU2sy3VyWI6PsP8AymUQ976Z/6FAiJ7s/AbDECnsXkP/TrxxV7iHYLeG8CNP9bF7V1UvTaZ6pAT8LiAsW9IIQKBgQCq+CKPOIAdwMXGv/fPEP2vHY28UG0u1LflEp8lch8CMd49jk9qKD7DhDKFGsg79JKRzi8VOhCYqmJwIrJXx/lDhWhE2sBK05ekItLsEfttmTl6PIvu5G3H3F4bbBdTuPR1YYIFscpuLsBLu7rVZGBlkV4gaIRghYRXddR+1o6q7wKBgAPW9AZ31tlgJSOOyvN7wfL1OUdYdv5BLvIfETH4dLe5tluuXcRqNj3KJiw7goAUnJclhQI48Mw4Xt79xl94chKhGKZPI/yaRAXNYhBqH0x5ZMKHcjEysWilPWvI+RhIIYll6Nb4dbb9y6Rz9XDIZGrDCKS0Z3LlUpaQfYRB7V8BAoGALJizMxay3I/3RwO2GU4+ThpwaUm1YTzdhyRXXQYqroDhjr77Wh6LWKa4It48kt8WCHB2+Zt+zsPLD6MNUDZ6f7Fh5GwHMr2E1ay7xhZetlT8mDUI71SoijSiW5bTcuRQ5/l6WA/rVNhfEqIydw1K09OacOuydBb/0WyL9FX1OwMCgYBfNLg3YZX4pQpcOPv22f6mDROMDi3YJvFGcM79ryPKTX6FgP4Tj7Hrf9xwm5Qd4j6AIL29Ttt+3xlo+dLm+T8b/e59Yw94h1ZliL9OCgWNzgcV90OctTECpIulJijQk835TkrJjsMe7uPUiUs50xXIWLC3KmCuU2EDgWq0YWICzw==";
    /**私钥 用于解密*/
    public static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhB7dwc6LkjRiGP5sTATheaB/y2AKOnbpx4rTA+M7/MGDegCN/7WaevbgFt23Kz1jd2xhhEI97k0Sz+UsKk5+W9yiGAFlNaEobHB5rU3KIUFdMOAB/XhgGmXGOoF2FXJFu2NBBmCjw1n+SUawegBXFFdbyMeKU1mnnLgzc8M6pFDVI49OSohB2bD7kuGFFz+8/jouItESp4dDKeG22QuAXCdcf+NtLfGBcyZyLfhOozd4JcQWmkipbmIy8Zs+IHccXh16GiwblnHLIVehQrrjCYoKDuA0ikIj0SJ/PF61fWnmywo35t6ggZWmkzuQkL6rULK8YFKplS0OjPw9JRhAzwIDAQAB";

    public static void main(String[] args) {
        String content = "枯藤老树昏鸦,小桥流水人家,古道西风瘦马。夕阳西下,断肠人在天涯。";
        try {

            //发送方
            /**1.AES 加密原文*/
            String aesKey = AESUtil.getAESKey(128, null);

            String contentEncrypt = AESUtil.encrypt(content, aesKey);
            System.out.println("AES密文::"+contentEncrypt);

            /**2.RSA 公钥加密AES的秘钥*/
            String aesKeyEncrypt = RSAUtil.encrypt(aesKey, PUBLIC_KEY);
            System.out.println("加密后的AES秘钥::"+aesKeyEncrypt);
            //发送密文contentEncrypt 和加密后的秘钥aesKeyEncrypt

            //接收方
            /**3.RSA 私钥解密获取AES 秘钥*/
            String aesKeyDecrypt = RSAUtil.decrypt(aesKeyEncrypt, PRIVATE_KEY);
            System.out.println("解密后的AES秘钥::"+aesKeyDecrypt);

            /**4.AES 解密获取原文*/
            String contentDecrypt = AESUtil.decrypt(contentEncrypt, aesKeyDecrypt);
            System.out.println("原文::"+contentDecrypt);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

输出内容:

AES秘钥::meueToop83cx+dRMx0+K+g==
AES密文::13bH6M6/TTVOIE9DUFu0F58j/BUAR9dnJL4DF8WWZJYW7U64KrvvivXB2hlbaDxi+pwpXR97I5icI9fThwylRNrIvuEsih/ugfGwBmFTj2py/DXbPoZ2bnQPNx6Yj9WPP47c0dCaWly4OqgVZkvSQA==
加密后的AES秘钥::UkhDS6Br2IN1PJpUcABnq4u3OibaHtFZSRnoXX4rRhjNy46zaYA+LeMPFM9aZHBQnYWrb8PYWwNuOpKVgBWRSGbzWuJ6rhVXSvWlmxVbcMDLsxebFJ0wfoPaxY0wWHORQGi3OPHNeyiUS9yKiZ+JKM8FmkGq81FSFJRv6HzLkh16TlMG0lTcSUQidKQmzxM5TZXHr+nW3FP+dicg4FAxI51lFijt/JfqnoagX2smorG12Ow3SqXGrOp8uY4gH6jikfhyVpP7eGHwqZWxKOTnBrGoVlqL7kF15JQvrMMhgzZC4gyS8MDFiELWgAatxqSMoiMafxMIs9AAuGye5wu1Og==
解密后的AES秘钥::meueToop83cx+dRMx0+K+g==
原文::枯藤老树昏鸦,小桥流水人家,古道西风瘦马。夕阳西下,断肠人在天涯。

参考自:https://blog.csdn.net/qq_42889895/article/details/106249724
https://blog.csdn.net/DamonREN/article/details/87601165

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值