javax.crypto。badpaddpaddingexception:给出的最终块在解密发送给服务器的字节时不能正确填充

时间:2021-06-07 18:32:20

I am creating a secure chat client and server combo that, when finished, will have multiple layers of encryption. However, I don't understand why I am getting this error. I know there are multiple questions out there with many different answers (some so different I don't understand how anyone gets their problem resolved), however I have yet to find one that I can understand enough of to fix this error.

我正在创建一个安全的聊天客户端和服务器组合,一旦完成,将具有多层加密。然而,我不明白为什么我得到这个错误。我知道有很多不同的问题,有很多不同的答案(有些非常不同,我不知道如何解决他们的问题),但是我还没有找到一个我能理解到的足以修正这个错误的问题。

Originally, this actually worked; it sent the key through without a problem. I don't remember changing any part of this code. Maybe someone can tell me what's wrong? I'll mark the line with the error.

最初,这实际上工作;它顺利地把钥匙送了过去。我不记得修改过这段代码的任何部分。也许有人能告诉我怎么了?我用错误标记这条线。

javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
    at javax.crypto.Cipher.doFinal(Cipher.java:2087)
    at secureserver.Server$1.run(Server.java:88)
    at java.lang.Thread.run(Unknown Source)

Part of Server that receives key

接收密钥的服务器的一部分

                        try {
                            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
                            KeySpec spec = new PBEKeySpec("i15646dont6321wanna".toCharArray(),"ahhalkdjfslk3205jlk3m4ljdfa85l".getBytes("UTF8"),65536,256);
                            SecretKey tmp = factory.generateSecret(spec);
                            SecretKey key = new SecretKeySpec(tmp.getEncoded(),"AES");

                            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                            byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                            IvParameterSpec ivspec = new IvParameterSpec(iv);
                            cipher.init(Cipher.DECRYPT_MODE, key, ivspec);

                            byte[] b = new byte[is.available()];
                            is.read(b);
/* Line 88 */               byte[] dec = cipher.doFinal(b);
                            SecretKey ck = new SecretKeySpec(dec,"AES");
                            Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
                            c.init(Cipher.ENCRYPT_MODE, ck, ivspec);
                            eciphers.put(client, c);
                            c.init(Cipher.DECRYPT_MODE, ck, ivspec);
                            dciphers.put(client, c);
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        } catch (NoSuchAlgorithmException e) {
                            e.printStackTrace();
                        } catch (InvalidKeySpecException e) {
                            e.printStackTrace();
                        } catch (NoSuchPaddingException e) {
                            e.printStackTrace();
                        } catch (InvalidKeyException e) {
                            e.printStackTrace();
                        } catch (InvalidAlgorithmParameterException e) {
                            e.printStackTrace();
                        } catch (IllegalBlockSizeException e) {
                            e.printStackTrace();
                        } catch (BadPaddingException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

Part of the client that sends key to server

客户端发送密钥到服务器的部分。

public void sendKey(SecretKey k) {
        try {
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            KeySpec spec = new PBEKeySpec("i15646dont6321wanna".toCharArray(),"ahhalkdjfslk3205jlk3m4ljdfa85l".getBytes("UTF8"),65536,256);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKey key = new SecretKeySpec(tmp.getEncoded(),"AES");
            Cipher ec = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            IvParameterSpec ivspec = new IvParameterSpec(iv);
            ec.init(Cipher.ENCRYPT_MODE, key, ivspec);

            byte[] ekey = ec.doFinal(k.getEncoded());
            os.write(ekey);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

1 个解决方案

#1


1  

It's probably your stream handling that causes this:

可能是您的流处理导致了以下情况:

byte[] b = new byte[is.available()];
is.read(b);

Is not a correct way of handling streams. Try a Java I/O tutorial to understand how to treat streams.

不是处理流的正确方法。尝试使用Java I/O教程了解如何处理流。


As a side note, for better and more legible exception handling:

作为补充说明,为了更好、更清晰地处理异常:

try {
    // handling Cipher code...
} catch (final IllegalBlockSizeException | BadPaddingException | IOException e) {
    // or use your own checked exception
    throw new IllegalArgumentException("Invalid ciphertext", e);
} catch (final GeneralSecurityException e) {
    throw new IllegalStateException("Cryptographic algorithms not available", e);
}

#1


1  

It's probably your stream handling that causes this:

可能是您的流处理导致了以下情况:

byte[] b = new byte[is.available()];
is.read(b);

Is not a correct way of handling streams. Try a Java I/O tutorial to understand how to treat streams.

不是处理流的正确方法。尝试使用Java I/O教程了解如何处理流。


As a side note, for better and more legible exception handling:

作为补充说明,为了更好、更清晰地处理异常:

try {
    // handling Cipher code...
} catch (final IllegalBlockSizeException | BadPaddingException | IOException e) {
    // or use your own checked exception
    throw new IllegalArgumentException("Invalid ciphertext", e);
} catch (final GeneralSecurityException e) {
    throw new IllegalStateException("Cryptographic algorithms not available", e);
}