You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中AES加密Jar文件后体积翻倍是否正常?

AES加密Jar中Class文件后体积翻倍的原因分析

这种体积大幅翻倍绝对不正常,AES加密本身只会带来极小的体积增长(PKCS5Padding最多为每个加密块补充16字节的填充),你的问题是代码逻辑存在两处关键错误:

1. JarOutputStream未启用压缩,导致所有内容以未压缩格式存储

原Jar文件本质是带签名的ZIP包,其中的文件(包括.class文件)默认是经过DEFLATE压缩的。但你的代码中创建JarOutputStream时使用了无参构造:

JarOutputStream dst_jar = new JarOutputStream(dst_fos);

这个构造函数默认不启用压缩,而你通过JarFile读取entry时,会自动解压得到原始未压缩的字节数据,随后直接写入新Jar时没有重新压缩——这会导致原本压缩过的非class文件体积直接膨胀,再加上加密后的.class文件无法被压缩(加密后的数据是伪随机的,压缩率几乎为0),最终整体体积翻倍。

修复方法:创建JarOutputStream时指定压缩级别,比如启用最高压缩:

JarOutputStream dst_jar = new JarOutputStream(dst_fos, new Deflater(Deflater.BEST_COMPRESSION));

2. 复用Cipher实例加密多个独立文件的错误

你在main方法中初始化了一次Cipher,然后循环复用它加密所有.class文件。在AES/CBC模式下,每次调用doFinal()后,Cipher的IV会被更新为最后一个密文块,这会导致后续的.class文件加密依赖前一个文件的密文上下文,不仅存在严重的安全风险(破坏加密的独立性),还可能因上下文混乱导致额外的字节填充问题。

修复方法:每个.class文件加密前,重新初始化Cipher(使用相同的密钥,但为每个文件生成独立IV,将IV与密文一起存储,解密时先读取IV再解密):

// 在处理每个class文件时重新初始化Cipher
if(name.endsWith(".class")){
    try {
        // 生成随机IV(16字节,AES块大小)
        byte[] newIv = new byte[16];
        new SecureRandom().nextBytes(newIv);
        IvParameterSpec newIvSpec = new IvParameterSpec(newIv);
        Cipher fileCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        fileCipher.init(Cipher.ENCRYPT_MODE, aesKey, newIvSpec);
        
        byte[] encryptedData = fileCipher.doFinal(bytes);
        // 将IV和密文拼接,后续解密时先取前16字节作为IV
        ByteArrayOutputStream combinedBaos = new ByteArrayOutputStream();
        combinedBaos.write(newIv);
        combinedBaos.write(encryptedData);
        bytes = combinedBaos.toByteArray();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

额外验证

你可以先测试不加密任何.class文件,直接将原Jar的内容复制到新Jar中,看看体积是否依然翻倍——如果是,就坐实了是未启用压缩的问题。

内容的提问来源于stack exchange,提问作者Content

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 11:13:10