• Java实现AES对称加密和解密


    原文链接:https://blog.csdn.net/xietansheng/article/details/88389515

    AES(Advanced Encryption Standard,高级加密标准)是一种对称加密算法,加密和解密使用相同的密钥。

    1. AES 加密/解密 代码实例

    Java 代码实现 AES 加密/解密 一般步骤:先根据原始的密码(字节数组/字符串)生成 AES密钥对象;再使用 AES密钥对象 加密/解密 数据。

    package com.xiets.aes;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import java.security.SecureRandom;
    
    /**
     * @author xietansheng
     */
    public class Main {
    
        public static void main(String[] args) throws Exception {
            String content = "Hello world!";        // 原文内容
            String key = "123456";                  // AES加密/解密用的原始密码
    
            // 加密数据, 返回密文
            byte[] cipherBytes = encrypt(content.getBytes(), key.getBytes());
    
            // 解密数据, 返回明文
            byte[] plainBytes = decrypt(cipherBytes, key.getBytes());
    
            // 输出解密后的明文: "Hello world!"
            System.out.println(new String(plainBytes));
        }
    
        /**
         * 生成密钥对象
         */
        private static SecretKey generateKey(byte[] key) throws Exception {
            // 根据指定的 RNG 算法, 创建安全随机数生成器
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            // 设置 密钥key的字节数组 作为安全随机数生成器的种子
            random.setSeed(key);
    
            // 创建 AES算法生成器
            KeyGenerator gen = KeyGenerator.getInstance("AES");
            // 初始化算法生成器
            gen.init(128, random);
    
            // 生成 AES密钥对象, 也可以直接创建密钥对象: return new SecretKeySpec(key, ALGORITHM);
            return gen.generateKey();
        }
    
        /**
         * 数据加密: 明文 -> 密文
         */
        public static byte[] encrypt(byte[] plainBytes, byte[] key) throws Exception {
            // 生成密钥对象
            SecretKey secKey = generateKey(key);
    
            // 获取 AES 密码器
            Cipher cipher = Cipher.getInstance("AES");
            // 初始化密码器(加密模型)
            cipher.init(Cipher.ENCRYPT_MODE, secKey);
    
            // 加密数据, 返回密文
            return cipher.doFinal(plainBytes);
        }
    
        /**
         * 数据解密: 密文 -> 明文
         */
        public static byte[] decrypt(byte[] cipherBytes, byte[] key) throws Exception {
            // 生成密钥对象
            SecretKey secKey = generateKey(key);
    
            // 获取 AES 密码器
            Cipher cipher = Cipher.getInstance("AES");
            // 初始化密码器(解密模型)
            cipher.init(Cipher.DECRYPT_MODE, secKey);
    
            // 解密数据, 返回明文
            return cipher.doFinal(cipherBytes);
        }
    
    }
    
    • 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
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    2. AES 工具类封装: AESUtils.java

    为了方便直接使用,将 AES 加密/解密相关方法封装成工具类,并且支持对文件的 AES 加密/解密。

    一共封装 4 个公共静态方法:

    // 数据加密: 明文 -> 密文
    byte[] encrypt(byte[] plainBytes, byte[] key)
    // 数据解密: 密文 -> 明文
    byte[] decrypt(byte[] cipherBytes, byte[] key)
    
    // 加密文件: 明文输入 -> 密文输出
    void   encryptFile(File plainIn, File cipherOut, byte[] key)
    // 解密文件: 密文输入 -> 明文输出
    void   decryptFile(File cipherIn, File plainOut, byte[] key)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    AESUtils.java完整代码:

    package com.xiets.aes;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import java.io.Closeable;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.security.SecureRandom;
    
    /**
     * AES 对称算法加密/解密工具类
     *
     * @author xietansheng
     */
    public class AESUtils {
    
        /** 密钥长度: 128, 192 or 256 */
        private static final int KEY_SIZE = 128;
    
        /** 加密/解密算法名称 */
        private static final String ALGORITHM = "AES";
    
        /** 随机数生成器(RNG)算法名称 */
        private static final String RNG_ALGORITHM = "SHA1PRNG";
    
        /**
         * 生成密钥对象
         */
        private static SecretKey generateKey(byte[] key) throws Exception {
            // 创建安全随机数生成器
            SecureRandom random = SecureRandom.getInstance(RNG_ALGORITHM);
            // 设置 密钥key的字节数组 作为安全随机数生成器的种子
            random.setSeed(key);
    
            // 创建 AES算法生成器
            KeyGenerator gen = KeyGenerator.getInstance(ALGORITHM);
            // 初始化算法生成器
            gen.init(KEY_SIZE, random);
    
            // 生成 AES密钥对象, 也可以直接创建密钥对象: return new SecretKeySpec(key, ALGORITHM);
            return gen.generateKey();
        }
    
        /**
         * 数据加密: 明文 -> 密文
         */
        public static byte[] encrypt(byte[] plainBytes, byte[] key) throws Exception {
            // 生成密钥对象
            SecretKey secKey = generateKey(key);
    
            // 获取 AES 密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 初始化密码器(加密模型)
            cipher.init(Cipher.ENCRYPT_MODE, secKey);
    
            // 加密数据, 返回密文
            byte[] cipherBytes = cipher.doFinal(plainBytes);
    
            return cipherBytes;
        }
    
        /**
         * 数据解密: 密文 -> 明文
         */
        public static byte[] decrypt(byte[] cipherBytes, byte[] key) throws Exception {
            // 生成密钥对象
            SecretKey secKey = generateKey(key);
    
            // 获取 AES 密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 初始化密码器(解密模型)
            cipher.init(Cipher.DECRYPT_MODE, secKey);
    
            // 解密数据, 返回明文
            byte[] plainBytes = cipher.doFinal(cipherBytes);
    
            return plainBytes;
        }
    
        /**
         * 加密文件: 明文输入 -> 密文输出
         */
        public static void encryptFile(File plainIn, File cipherOut, byte[] key) throws Exception {
            aesFile(plainIn, cipherOut, key, true);
        }
    
        /**
         * 解密文件: 密文输入 -> 明文输出
         */
        public static void decryptFile(File cipherIn, File plainOut, byte[] key) throws Exception {
            aesFile(plainOut, cipherIn, key, false);
        }
    
        /**
         * AES 加密/解密文件
         */
        private static void aesFile(File plainFile, File cipherFile, byte[] key, boolean isEncrypt) throws Exception {
            // 获取 AES 密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 生成密钥对象
            SecretKey secKey = generateKey(key);
            // 初始化密码器
            cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secKey);
    
            // 加密/解密数据
            InputStream in = null;
            OutputStream out = null;
    
            try {
                if (isEncrypt) {
                    // 加密: 明文文件为输入, 密文文件为输出
                    in = new FileInputStream(plainFile);
                    out = new FileOutputStream(cipherFile);
                } else {
                    // 解密: 密文文件为输入, 明文文件为输出
                    in = new FileInputStream(cipherFile);
                    out = new FileOutputStream(plainFile);
                }
    
                byte[] buf = new byte[1024];
                int len = -1;
    
                // 循环读取数据 加密/解密
                while ((len = in.read(buf)) != -1) {
                    out.write(cipher.update(buf, 0, len));
                }
                out.write(cipher.doFinal());    // 最后需要收尾
    
                out.flush();
    
            } finally {
                close(in);
                close(out);
            }
        }
    
        private static void close(Closeable c) {
            if (c != null) {
                try {
                    c.close();
                } catch (IOException e) {
                    // nothing
                }
            }
        }
    
    }
    
    • 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
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152

    AESUtils 工具类的使用实例:

    package com.xiets.aes;
    
    import java.io.File;
    
    /**
     * @author xietansheng
     */
    public class Main {
    
        public static void main(String[] args) throws Exception {
            String content = "Hello world!";        // 原文内容
            String key = "123456";                  // AES加密/解密用的原始密码
    
            // 加密数据, 返回密文
            byte[] cipherBytes = AESUtils.encrypt(content.getBytes(), key.getBytes());
            // 解密数据, 返回明文
            byte[] plainBytes = AESUtils.decrypt(cipherBytes, key.getBytes());
            // 输出解密后的明文: "Hello world!"
            System.out.println(new String(plainBytes));
    
            /*
             * AES 对文件的加密/解密
             */
            // 将 文件demo.jpg 加密后输出到 文件demo.jpg_cipher
            AESUtils.encryptFile(new File("demo.jpg"), new File("demo.jpg_cipher"), key.getBytes());
            // 将 文件demo.jpg_cipher 解密后输出到 文件demo.jpg_plain
            AESUtils.decryptFile(new File("demo.jpg_cipher"), new File("demo.jpg_plain"), key.getBytes());
    
            // 对比 原文件demo.jpg 和 解密得到的文件demo.jpg_plain 两者的 MD5 将会完全相同
        }
    
    }
  • 相关阅读:
    时隔三个月,不言谢归来了。学习播客继续更新日常所学。
    一个网易云音乐的外链URL简单的获取方法
    VisualStudioCode常用主题,与插件设置
    页面a标签统一跳转方法:base 标签
    Web前端开发规范(记录一):团队约定-基本原则
    JS中,正则表达式:match(/^(.*)(.)(.{1,8})$/)[3]分析
    Morgan模块使用
    Config模块使用
    MongoDB安装
    JSP-九大内置对象
  • 原文地址:https://www.cnblogs.com/fswhq/p/13915726.html
Copyright © 2020-2023  润新知