DES加密解密报错:解密输入长度需为8的倍数,求解决方案
搞定DES解密时的「Input length must be multiple of 8」报错
兄弟,我一眼就看出问题出在哪了——DES是块加密算法,每块必须是8字节,加上你可能没正确配置填充模式,才触发了这个报错。结合你要用固定密钥加密个人非敏感数据的需求,我给你一步步解决:
一、为啥会报这个错?
DES每次处理的明文/密文块大小固定是8字节,如果你的输入长度不是8的倍数,又没开自动填充,解密时自然就会炸。而且很多人容易忽略:加密后的字节数组不能直接转字符串(会乱码丢字节),解密时拿到的字节长度不对也会触发这个错误。
另外你的密钥"eightkey"是8个字符,转成字节数组刚好8字节,这部分是符合DES要求的(DES密钥必须是8字节),这点没问题,但要确保编码固定(比如UTF-8),避免不同环境下密钥变样。
二、直接给你能用的完整代码
我把正确的加密解密逻辑写好了,直接拿去用,注释都给你标清楚了:
import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeySpec; import java.util.Base64; public class DesEncryptor { // 你的固定8字节密钥,对应字符串"eightkey"的UTF-8编码 private static final byte[] FIXED_DES_KEY = "eightkey".getBytes(); // 关键!指定ECB模式+PKCS5填充,自动处理长度问题 private static final String DES_TRANSFORMATION = "DES/ECB/PKCS5Padding"; // 加密方法:明文转Base64编码的密文 public static String encrypt(String plainText) throws Exception { SecretKey desKey = new SecretKeySpec(FIXED_DES_KEY, "DES"); Cipher cipher = Cipher.getInstance(DES_TRANSFORMATION); cipher.init(Cipher.ENCRYPT_MODE, desKey); // 加密后转Base64,避免乱码 byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8")); return Base64.getEncoder().encodeToString(encryptedBytes); } // 解密方法:Base64密文转明文 public static String decrypt(String encryptedBase64) throws Exception { SecretKey desKey = new SecretKeySpec(FIXED_DES_KEY, "DES"); Cipher cipher = Cipher.getInstance(DES_TRANSFORMATION); cipher.init(Cipher.DECRYPT_MODE, desKey); // 先解码Base64得到加密后的字节数组 byte[] encryptedBytes = Base64.getDecoder().decode(encryptedBase64); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes, "UTF-8"); } // 测试用例 public static void main(String[] args) throws Exception { String myData = "我的个人小数据"; String encrypted = encrypt(myData); System.out.println("加密后:" + encrypted); String decrypted = decrypt(encrypted); System.out.println("解密后:" + decrypted); } }
三、核心要点给你划重点
- 填充模式必须加:
PKCS5Padding会自动在加密时给不足8字节的内容补位,解密时自动去掉补位,完美解决长度问题 - 一定要用Base64:加密后的字节数组直接转字符串会有乱码、字节丢失,用Base64转成可打印的字符串,解密时再解码回去,保证字节完整
- 加密解密要配套:加密用的模式、填充、密钥,解密时必须完全一致,不然肯定出问题
四、给你排查原有代码的方向
- 看看你原来的
Cipher.getInstance()是不是只写了"DES",没加"/ECB/PKCS5Padding"?这会默认用NoPadding,要求输入必须是8字节倍数 - 加密后的结果是不是直接转成字符串存了?改成Base64编码就好
- 确认密钥的编码是不是统一,比如都是UTF-8,避免不同环境下转字节数组不一样
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

