• 常用对称加密算法之AES算法-CBC模式


    这个需求很简单就是存储数据库密码,因为链接数据库的需要用到,加密就必须要用对称加密算法,于是简单调研了一下对称加密算法,经过对比最后选择了AES算法-CBC模式

    怎么理解对称加密

    加密:接收秘钥key和明文,然后输出密文。
    解密:通过key解密密文,得到明文

    例: 加密 123 =》AES( 123 + key ) =》@#$ 解密 @#$ =》AES( key + @#$ ) =》123

    对比

    这里简单对我了解过的对称加密算法做个比较

    算法密钥长度运算速度安全性资源消耗
    DES56/64较快低(完全依赖密钥,易受穷举搜索法攻击)
    AES128/192/256高(ECB模式生成固定密钥安全性低,CBC模式每次生成的密文都不同安全性高)
    IDEA128较慢高(军事级,可抗差值分析和相关分析)

    1、DES(Data Encryption Standard):对称算法,数据加密标准,速度较快,适用于加密大量数据的场合;
    2、IDEA(International Data Encryption Algorithm)国际数据加密算法,使用 128位密钥提供非常强的安全性;
    3、AES(Advanced Encryption Standard):高级加密标准,对称算法,是下一代的加密算法标准,速度快,安全级别高,在21世纪AES 标准的一个实现是 Rijndael算法;

    密钥长度直接决定加密强度,DES算法由于密钥过短,可以在短时间内被暴力破解,所以现在已经不安全了。

    算法选择

    既然要使用对称加密算法,那么就必须要考虑两点,安全性性能,那么针对上面三种算法,显而易见的AES的CBC模式是不二之选

    代码demo实现

    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import javax.xml.bind.DatatypeConverter;
    import java.nio.charset.StandardCharsets;
    import java.security.SecureRandom;
    
    public class SecretUtil {
        //这里需要设置你的32位字节密钥
        public static final String ENCRYPT_OR_DECRYPT_KEY = "1234567890abcdef1234567890abcdef";
        // 256位密钥 = 32 bytes Key:
        //CBC模式是安全性较高的AES加密模式,它需要一个随机数作为IV参数,这样对于同一份明文,每次生成的密文都不同
        public static final byte[] BYTES_KEY = ENCRYPT_OR_DECRYPT_KEY.getBytes(StandardCharsets.UTF_8);
        public static final String INSTANCE = "AES/CBC/PKCS5Padding";
        public static final String AES = "AES";
    
        public static void main(String[] args) throws Exception {
            String password = "你来打我呀!";
            String encryptStr1 = encrypt(password);
            System.out.println("第一次加密:" + encryptStr1);
            String decryptStr1 = decrypt(encryptStr1);
            System.out.println("第一次解密:" + decryptStr1);
    
            String encryptStr2 = encrypt(password);
            System.out.println("我每次加密都不一样:" + encryptStr2);
            String decryptStr2 = decrypt(encryptStr1);
            System.out.println("但我每次都能得到你:" + decryptStr2);
        }
    
        // 加密
        public static String encrypt(String password) throws Exception {
            Cipher cipher = Cipher.getInstance(INSTANCE);
            SecretKeySpec keySpec = new SecretKeySpec(BYTES_KEY, AES);
            // CBC模式需要生成一个16 bytes的initialization vector
            SecureRandom sr = SecureRandom.getInstanceStrong();
            byte[] iv = sr.generateSeed(16);
            IvParameterSpec ivps = new IvParameterSpec(iv);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivps);
            byte[] data = cipher.doFinal(password.getBytes(StandardCharsets.UTF_8));
            // IV不需要保密,把IV和密文一起返回
            return DatatypeConverter.printBase64Binary(join(iv, data));
        }
    
        // 解密
        public static String decrypt(String password) throws Exception {
            byte[] iv = new byte[16];
            byte[] input = DatatypeConverter.parseBase64Binary(password);
            byte[] data = new byte[input.length - 16];
            // 把password分割成IV和密文
            System.arraycopy(input, 0, iv, 0, 16);
            System.arraycopy(input, 16, data, 0, data.length);
            // 解密
            Cipher cipher = Cipher.getInstance(INSTANCE);
            SecretKeySpec keySpec = new SecretKeySpec(BYTES_KEY, AES);
            IvParameterSpec ivps = new IvParameterSpec(iv);
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivps);
            return new String(cipher.doFinal(data), StandardCharsets.UTF_8);
        }
    
        public static byte[] join(byte[] bs1, byte[] bs2) {
            byte[] r = new byte[bs1.length + bs2.length];
            System.arraycopy(bs1, 0, r, 0, bs1.length);
            System.arraycopy(bs2, 0, r, bs1.length, bs2.length);
            return r;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    输出验证:
    在这里插入图片描述

    好了,对称加密算法之AES算法-CBC模式的简单应用就介绍到这里

    参考文章:廖雪峰的官方网站-对称加密算法

  • 相关阅读:
    java毕业设计海滨体育馆管理系统(附源码、数据库)
    如何看待服装订单外流现象?
    Mybatis_plus-逻辑删除、通用枚举、自动填充、插件等
    基于R语言平台Biomod2模型的物种分布建模与可视化分析
    策略验证_卖出口诀_三种图线交叉点卖出股票需抢先
    「 程序员的风险控制」两三百实现医疗自由,不怕学习工作太拼生病花大钱
    CSS面试题整理
    C语言进阶——程序环境和预处理
    ​力扣解法汇总1779. 找到最近的有相同 X 或 Y 坐标的点
    PGA-Net:基于金字塔特征融合与全局上下文注意力网络的自动表面缺陷检测
  • 原文地址:https://blog.csdn.net/m0_37482190/article/details/127427270