美文网首页
Java加密-AES加解密

Java加密-AES加解密

作者: 张明学 | 来源:发表于2020-08-08 19:16 被阅读0次

    Java简单实现

    public class AESUtil {
    
        private static final String KEY_ALGORITHM = "AES";
        /**
         * 默认的加密算法
         */
        private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
        
        /**
         * 随机生成密钥
         *
         * @return
         */
        public static String getAESRandomKey() {
            SecureRandom random = new SecureRandom();
            long randomKey = random.nextLong();
            return String.valueOf(randomKey);
        }
    
        /**
         * AES 加密操作
         *
         * @param content 待加密内容
         * @param key     加密密钥
         * @return 返回Base64转码后的加密数据
         */
        public static String encrypt(String content, String key) throws Exception {
            try {
                // 创建密码器
                Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
                byte[] byteContent = content.getBytes("utf-8");
                // 初始化为加密模式的密码器
                cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));
                // 加密
                byte[] result = cipher.doFinal(byteContent);
                //通过Base64转码返回
                return byte2Base64(result);
            } catch (Exception ex) {
                log.error("加密失败", ex);
            }
    
            return null;
        }
    
        /**
         * AES 解密操作
         *
         * @param content
         * @param key
         * @return
         */
        public static String decrypt(String content, String key) {
            try {
                //实例化
                Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
                //使用密钥初始化,设置为解密模式
                cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));
                //执行操作
                byte[] result = cipher.doFinal(base642Byte(content));
                return new String(result, "utf-8");
            } catch (Exception ex) {
                log.error("解密失败", ex);
            }
    
            return null;
        }
    
        /**
         * 生成加密秘钥
         *
         * @return
         */
        private static SecretKeySpec getSecretKey(final String key) {
            //返回生成指定算法密钥生成器的 KeyGenerator 对象
            try {
                KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
                // 此类提供加密的强随机数生成器 (RNG),该实现在windows上每次生成的key都相同,但是在部分linux或solaris系统上则不同。
                // SecureRandom random = new SecureRandom(key.getBytes());
                // 指定算法名称,不同的系统上生成的key是相同的。
                SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
                random.setSeed(key.getBytes());
                //AES 要求密钥长度为 128
                kg.init(128, random);
                //生成一个密钥
                SecretKey secretKey = kg.generateKey();
                // 转换为AES专用密钥
                return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);
            } catch (NoSuchAlgorithmException ex) {
                log.info("生成加密秘钥异常!", ex);
            }
            return null;
        }
    
        /**
         * 字节数组转Base64编码
         *
         * @param bytes
         * @return
         */
        public static String byte2Base64(byte[] bytes) {
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(bytes);
        }
    
        /**
         * Base64编码转字节数组
         *
         * @param base64Key
         * @return
         * @throws IOException
         */
        public static byte[] base642Byte(String base64Key) throws IOException {
            BASE64Decoder decoder = new BASE64Decoder();
            return decoder.decodeBuffer(base64Key);
        }
    }
    

    测试

    @Test
    public void aseTest() throws Exception {
        String content = "hello,您好";
        String key = "sde@5f98H*^hsff%dfs$r344&df8543*er";
        System.out.println("原文=" + content);
        String s1 = AESUtil.encrypt(content, key);
        System.out.println("加密结果=" + s1);
        System.out.println("解密结果="+AESUtil.decrypt(s1, key));
    }
    

    结果:

    原文=hello,您好
    加密结果=zcMUh2txC6JxbGqKQeZ/kA==
    解密结果=hello,您好
    

    常见问题:

    1、Linux下运行下报javax.crypto.BadPaddingException:Given final block not properly padded

    原因:SecureRandom 实现完全随操作系统本身的內部状态,该实现在 windows 上每次生成的 key 都相同,但是在部分 linux 或solaris系统上则不同。除非调用方在调用 getInstance 方法,然后调用 setSeed方法。

    方法:

    // SecureRandom强随机数生成器,完全随操作系统本身的內部状态
    SecureRandom random = new SecureRandom(key.getBytes());
    // 改成:指定算法名称
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
    random.setSeed(key.getBytes());
    

    Java-加密篇
    Java加解-RSA加解密
    Java加密-Signature数据签名
    Java加密-AES加解密
    Java加密-密钥的保存与获取

    相关文章

      网友评论

          本文标题:Java加密-AES加解密

          本文链接:https://www.haomeiwen.com/subject/atkxdktx.html