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

AES对称加密:客户端发加密数据至服务器解密时出现BadPaddingException

解决AES解密时的BadPaddingException问题

看起来你遇到的这个BadPaddingException主要是两个小细节处理错误导致的,咱们一步步梳理和修正:

问题1:服务器错误处理了接收到的加密数据长度

你在服务器里直接用packet.getData()获取数据,但这个方法返回的是你初始化的1024字节数组——而客户端实际发送的加密数据长度远小于这个值,数组里多余的部分都是默认填充的0字节。当你把包含这些无效字节的数组传给cipher.doFinal()时,AES的PKCS5填充验证就会失败,因为这些额外的0不符合填充规则。

正确的做法是获取数据包的有效长度,然后截取对应长度的字节数组来解密:

byte[] EncryptedData = Arrays.copyOfRange(packet.getData(), 0, packet.getLength());

问题2:解密时Cipher初始化参数错误

在解密模式初始化Cipher时,你写了:

cipher.init(Cipher.DECRYPT_MODE,secretKey, cipher.getParameters());

但此时cipher刚被实例化,还没有任何有效参数,传递cipher.getParameters()完全没必要(而且在ECB模式下,AES本来就不需要额外的算法参数)。直接使用两个参数的init方法即可:

cipher.init(Cipher.DECRYPT_MODE, secretKey);

另外,服务器里打印解密后的数据时,直接输出plainBytesDecrypted只会显示字节数组的内存地址,应该转成字符串才能看到明文:

System.out.println("Decrypted data: " + new String(plainBytesDecrypted));

修正后的完整服务器代码

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class Server {
    public static void main(String[] args) throws IOException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
        int port = 56321;
        byte[] keySymme = { 0x74, 0x68, 0x69, 0x73, 0x49, 0x73, 0x41, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79 };//"thisIsASecretKey";
        SecretKeySpec secretKey = new SecretKeySpec(keySymme, "AES");
        
        DatagramSocket socket = new DatagramSocket(port);
        DatagramPacket packet = null;
        byte[] data = null;
        
        while(true){
            data = new byte[1024];
            packet = new DatagramPacket(data, data.length);
            socket.receive(packet);
            
            int port2 = packet.getPort();
            InetAddress address = packet.getAddress();
            
            // 修正:获取有效加密数据
            byte[] EncryptedData = Arrays.copyOfRange(packet.getData(), 0, packet.getLength());
            
            System.out.println("Address " + address + " Port " + port2 + " Encrypted data length: " + EncryptedData.length);
            System.out.println("Listening...");
            
            try {
                Cipher cipher = Cipher.getInstance("AES");
                // 修正:解密模式初始化,不需要额外参数
                cipher.init(Cipher.DECRYPT_MODE, secretKey);
                byte[] plainBytesDecrypted = cipher.doFinal(EncryptedData);
                // 修正:转成字符串输出明文
                System.out.println("Decrypted data: " + new String(plainBytesDecrypted));
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
}

额外提示

虽然你的代码现在能正常工作,但ECB模式是不安全的(它不对数据做混淆,相同的明文块会得到相同的密文块),实际生产环境建议使用更安全的模式,比如AES/CBC/PKCS5Padding或者AES/GCM/NoPadding,不过这需要额外处理IV(初始化向量)的传递,感兴趣的话可以深入了解下。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:27:12