使用填充密码解密时,输入长度必须是16的倍数

hkg*_*ile 8 java

我有一个服务器和客户端套接字程序,服务器向客户端发送加密消息,即服务器端代码:

cipher2 = Cipher.getInstance("AES"); 
secretKeySpec = new SecretKeySpec(decryptedText, "AES");
cipher2.init(Cipher.ENCRYPT_MODE, secretKeySpec);
feedback = "Your answer is wrong".getBytes();
cipher2.doFinal(feedback);
dos.writeInt(feedback.length);
dos.write(feedback);
Run Code Online (Sandbox Code Playgroud)

客户端代码:

int result_len = 0;
result_len = din.readInt();            
byte[] result_Bytes = new byte[result_len];
din.readFully(result_Bytes);
cipher2 = Cipher.getInstance("AES");
cipher2.init(Cipher.DECRYPT_MODE, aesKey);             
byte[] encrypt = cipher2.doFinal(result_Bytes);
Run Code Online (Sandbox Code Playgroud)

抛出异常 byte[] encrypt = cipher2.doFinal(result_Bytes);

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750)
    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:2086)
Run Code Online (Sandbox Code Playgroud)

问题是什么?

Ani*_*rni 17

这是一个非常古老的问题,但我的回答可能会对某人有所帮助。

  • 在 encrypt 方法中,不要忘记将您的字符串编码为 Base64
  • 在解密方法中,不要忘记将您的字符串解码为 Base64

下面是工作代码

    import java.util.Arrays;
    import java.util.Base64;

    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;

    public class EncryptionDecryptionUtil {

    public static String encrypt(final String secret, final String data) {


        byte[] decodedKey = Base64.getDecoder().decode(secret);

        try {
            Cipher cipher = Cipher.getInstance("AES");
            // rebuild key using SecretKeySpec
            SecretKey originalKey = new SecretKeySpec(Arrays.copyOf(decodedKey, 16), "AES");
            cipher.init(Cipher.ENCRYPT_MODE, originalKey);
            byte[] cipherText = cipher.doFinal(data.getBytes("UTF-8"));
            return Base64.getEncoder().encodeToString(cipherText);
        } catch (Exception e) {
            throw new RuntimeException(
                    "Error occured while encrypting data", e);
        }

    }

    public static String decrypt(final String secret,
            final String encryptedString) {


        byte[] decodedKey = Base64.getDecoder().decode(secret);

        try {
            Cipher cipher = Cipher.getInstance("AES");
            // rebuild key using SecretKeySpec
            SecretKey originalKey = new SecretKeySpec(Arrays.copyOf(decodedKey, 16), "AES");
            cipher.init(Cipher.DECRYPT_MODE, originalKey);
            byte[] cipherText = cipher.doFinal(Base64.getDecoder().decode(encryptedString));
            return new String(cipherText);
        } catch (Exception e) {
            throw new RuntimeException(
                    "Error occured while decrypting data", e);
        }
    }


    public static void main(String[] args) {

        String data = "This is not easy as you think";
        String key = "---------------------------------";
        String encrypted = encrypt(key, data);
        System.out.println(encrypted);
        System.out.println(decrypt(key, encrypted));
      }
  }
Run Code Online (Sandbox Code Playgroud)

对于生成密钥,您可以使用以下类

    import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class SecretKeyGenerator {

    public static void main(String[] args) throws NoSuchAlgorithmException {

        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");

        SecureRandom secureRandom = new SecureRandom();
        int keyBitSize = 256;
        keyGenerator.init(keyBitSize, secureRandom);

        SecretKey secretKey = keyGenerator.generateKey();

 System.out.println(Base64.getEncoder().encodeToString(secretKey.getEncoded()));
    }

}
Run Code Online (Sandbox Code Playgroud)


vsi*_*ngh 8

有一个类似的问题.但重要的是要了解根本原因,并且可能因不同的用例而异.

方案1
您试图解密首先未正确编码的值.

byte[] encryptedBytes = Base64.decodeBase64(encryptedBase64String);
Run Code Online (Sandbox Code Playgroud)

如果String由于某种原因配置错误或者编码不正确,您会看到错误"使用填充密码解密时输入长度必须是16的倍数"

场景2
现在,如果你在url中使用这个编码的字符串(试图在url中传入base64Encoded值,它将失败.你应该做URLEncoding,然后传入令牌,它将工作.

场景3
当与其中一个供应商集成时,我们发现我们必须使用URLEncoder对Base64进行加密,但我们不需要解码它,因为它是由供应商内部完成的