javax.crypto.IllegalBlockSizeException:输入长度不是16个字节的倍数

彩虹

我有一个包含一些对象的ArrayList。对象是用于登录/传递的容器。
我尝试对它们进行解码,因为在再次启动后我必须将它们序列化为本地文件以进行娱乐。
问题是我收到加密时

javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes
    at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1039)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:983)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:845)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)

而且我完全不明白为什么。我认为Base64应该处理这个问题。但是,也许我不太了解它的含义。
我用来加密/解密

public class Move
{
    private static Move instance;

    String key = "pT5IkWNR90gJo5YM";
    String initVector = "RandomInitVector";
    Cipher cipher;


    private Move()
    {
//      try
//      {
//          cipher = Cipher.getInstance("AES/CBC/NoPadding");
//      }
//      catch (NoSuchAlgorithmException | NoSuchPaddingException e)
//      {
//          e.printStackTrace();
//      }
    }


    public void saveData(ArrayList<Account> dataToSave)
    {
        try
        {
            FileOutputStream fileOut = new FileOutputStream(Config.SERIAL_FILE);
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(encrypt(dataToSave));
            out.close();
            fileOut.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }


    @SuppressWarnings("unchecked")
    public ArrayList<Account> loadData()
    {
        ArrayList<Account> loadedData = new ArrayList<Account>();
        File f = new File(Config.SERIAL_FILE);
        if (f.exists())
        {
            try
            {
                FileInputStream fileIn = new FileInputStream(Config.SERIAL_FILE);
                ObjectInputStream in = new ObjectInputStream(fileIn);
                loadedData = (ArrayList<Account>) in.readObject();
                in.close();
                fileIn.close();
            }
            catch (IOException | ClassNotFoundException e)
            {
                e.printStackTrace();
            }
            loadedData = decrypt(loadedData);
        }
        else
        {
            loadedData = new ArrayList<Account>();
        }
        return loadedData;
    }


    private ArrayList<Account> encrypt(List<Account> decrypted)
    {
        ArrayList<Account> encrypted = new ArrayList<Account>();

        try
        {
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            cipher = Cipher.getInstance("AES/CBC/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            for (int i = 0; i < decrypted.size(); i++)
            {
                try
                {
                    byte[] login = cipher.doFinal(Base64.getDecoder().decode(decrypted.get(i).getLogin().getBytes()));
                    encrypted.add(new Account(login.toString(), "pass"));
                }
                catch (Exception ex)
                {
                    ex.printStackTrace();
                }
            }
        }
        catch (InvalidKeyException | InvalidAlgorithmParameterException | UnsupportedEncodingException | NoSuchAlgorithmException | NoSuchPaddingException e)
        {
            e.printStackTrace();
        }
        return encrypted;
    }


    private ArrayList<Account> decrypt(List<Account> encrypted)
    {
        ArrayList<Account> decrypted = new ArrayList<Account>();

        try
        {
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
            cipher = Cipher.getInstance("AES/CBC/NoPadding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

            for (int i = 0; i < encrypted.size(); i++)
            {
                byte[] login = cipher.doFinal(Base64.getDecoder().decode(encrypted.get(i).getLogin()));
                decrypted.add(new Account(new String(login), "pass"));
            }
        }
        catch (InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException | NoSuchAlgorithmException | NoSuchPaddingException e)
        {
            e.printStackTrace();
        }
        return decrypted;
    }


    public static Move getMove()
    {
        if (instance == null)
        {
            instance = new Move();
        }
        return instance;
    }
}
迪迪兹

AES块大小始终为128位,它必须以该数字的倍数接收输入。

较小的输入必须填充为16个字节,并为算法指定填充类型。

使用“ AES / CBC / PKCS5Padding”将达到目的。

cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

如果使用NoPadding,则必须实现自己的填充进行加密,并确保从解密结果字符串中删除该填充。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Java AES GCM javax.crypto.AEADBadTagException:标记不匹配

javax.crypto.spec.SecretKeySpec线程安全吗?

javax.crypto.Cipher对RSA使用哪种填充

javax.crypto.IllegalBlockSizeException:解密中的最后一个块不完整-解密加密的AES字符串

获取javax.crypto.IllegalBlockSizeException:使用填充密码解密时,输入长度必须是16的倍数吗?

javax.crypto.BadPaddingException

在哪里可以找到javax.crypto源代码?

javax.crypto.Cipher有多安全?

错误:com.sun.crypto.provider.AESCipher $ General无法转换为javax.crypto.CipherSpi

不断获取javax.crypto.IllegalBlockSizeException:使用填充密码解密时,输入长度必须为16的倍数

Crypto ++输出数据长度

JavaScript中用于javax.crypto的备用代码

javax.crypto.BadPaddingException:解密错误

RSA解密期间的javax.crypto.BadPaddingException

javax.crypto.IllegalBlockSizeException:密码函数:OPENSSL_internal:WRONG_FINAL_BLOCK_LENGTH

Python与Kotlin AES通信(javax.crypto.BadPaddingException)

AndroidX数据存储-AES / CBC / PKCS7-javax.crypto.IllegalBlockSizeException

javax.crypto库中AAD的GCM模式

我有javax.crypto.BadPaddingException:RSA密码术

AES解密:javax.crypto.IllegalBlockSizeException:解密中的最后一个块不完整

Java RSA实现:javax.crypto.BadPaddingException

javax.crypto.BadPaddingException:填充块损坏的异常

解密时出现错误javax.crypto.IllegalBlockSizeException:

AES加密期间出现javax.crypto.BadPaddingException错误

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

解密时出现 javax.crypto.IllegalBlockSizeException

Apache Commons Crypto - 获取 IllegalBlockSizeException

将 JSON 与 AES 一起使用会抛出 javax.crypto.IllegalBlockSizeException

javax.crypto.AEADBadTagException - AES/GCM/NoPadding 工作,然后不