Java 8使用AES/CBC/NoPadding解密文件却生成加密文件的问题
AES-CBC解密后文件仍加密的修复思路
以下是针对代码问题的具体修复方向:
密钥长度不符合AES-128要求
AES-128需要16字节(128位)的密钥,但你使用的"12345678"仅为8字节(UTF-8编码)。解密密钥必须与加密时使用的密钥完全一致:- 如果加密时是将短密钥补全至16字节(比如用0填充),解密时需执行相同操作:
byte[] keyBytes = "12345678".getBytes(StandardCharsets.UTF_8); byte[] aesKey = new byte[16]; System.arraycopy(keyBytes, 0, aesKey, 0, keyBytes.length); SecretKeySpec secretKeySpec = new SecretKeySpec(aesKey, "AES"); - 如果加密时使用密钥派生算法(如PBKDF2)生成密钥,解密时必须用相同的算法、盐、迭代次数生成一致的密钥。
- 如果加密时是将短密钥补全至16字节(比如用0填充),解密时需执行相同操作:
IV与加密时不匹配
CBC模式的初始化向量(IV)必须和加密阶段完全相同,不能硬编码为全0数组。通常加密时会将IV附加在密文头部(前16字节),解密时需先分离IV再解密:// 从密文头部提取IV(假设IV存储在密文前16字节) byte[] iv = Arrays.copyOfRange(inputBytes, 0, 16); byte[] ciphertext = Arrays.copyOfRange(inputBytes, 16, inputBytes.length); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); // 初始化Cipher后解密分离出的密文 cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] decryptedBytes = cipher.doFinal(ciphertext);填充模式不匹配
你指定了AES/CBC/NoPadding,但如果加密时使用了填充(如PKCS5Padding),解密时必须使用相同的填充模式。若加密端使用了填充,需将Cipher实例改为:Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");错误的填充模式会导致解密结果保留填充字节,看起来仍处于加密状态。
文件读取方式不可靠
fis.available()无法保证获取文件完整大小,可能导致读取的密文不完整,解密失败。建议使用NIO API读取整个文件:byte[] inputBytes = Files.readAllBytes(Paths.get(inputFile));二进制内容写入错误
若原文件是二进制类型(如图片、压缩包),将解密后的字节转为UTF-8字符串再写入会损坏内容。应直接写入字节数组:FileOutputStream fos = new FileOutputStream(outputFile); fos.write(decryptedBytes); fos.close();
内容的提问来源于stack exchange,提问作者Pier Zegarra Reymundo
相关产品推荐
相关产品推荐

