尝试使用 AES 加密和解密字符串时出现 IllegalBlockSizeException [英] IllegalBlockSizeException when trying to encrypt and decrypt a string with AES

查看:40
本文介绍了尝试使用 AES 加密和解密字符串时出现 IllegalBlockSizeException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个硬编码的密钥,我想用它在将字符串存储在 SharedPreferences 之前对其进行加密.这是我到目前为止的代码:

I have a hardcoded key with which I want to encrypt a string before storing it in SharedPreferences. This is the code I have so far:

public class TokenEncryptor {

    private final static String TOKEN_KEY = "91a29fa7w46d8x41";

    public static String encrypt(String plain) {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(new byte[16]);
            SecretKeySpec newKey = new SecretKeySpec(TOKEN_KEY.getBytes(), "AES");
            cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
            return new String(cipher.doFinal(plain.getBytes()));
        } catch (Exception e) {
            Ln.e(e);
            return null;
        }
    }

    public static String decrypt(String encoded) {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(new byte[16]);
            SecretKeySpec newKey = new SecretKeySpec(TOKEN_KEY.getBytes(), "AES");
            cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
            return new String(cipher.doFinal(encoded.getBytes()));
        } catch (Exception e) {
            Ln.e(e);
            return null;
        }
    }
}

它似乎在decrypt方法的末尾捕获异常:

It seems to be catching an exception at the end of decrypt method:

javax.crypto.IllegalBlockSizeException:错误:0606506D:数字信封例程:EVP_DecryptFinal_ex:最终块长度错误

有人能指出我正确的方向吗?我有一种感觉,我在实例化 IvParameterSpec 时做错了什么.

Can someone point me in the right direction? I have a feeling I'm doing something wrong instantiating IvParameterSpec.

推荐答案

当你用 AES 加密一个字符串时,你会得到一个字节数组.尝试将这些字节直接转换为字符串 (new String(cipher.doFinal(plaintextBytes))) 会导致各种问题.如果您要求加密方法的输出是字符串,请使用 Base64 而不是尝试直接转换.在您的解密方法中,在解密字节数组之前,将 Base64 字符串转换回字节数组.

When you encrypt a string with AES, you get an array of bytes back. Trying to convert those bytes directly to a string (new String(cipher.doFinal(plaintextBytes))) will cause all sorts of problems. If you require the output from your encryption method to be a string, then use Base64 rather than attempting a direct conversion. In your decryption method, convert the Base64 string back into a byte array before decrypting the byte array.

另外,不要使用 getBytes() 因为输出取决于系统默认值.使用 getBytes("utf-8") 或其他什么.这消除了歧义.

Also, do not use getBytes() since the output depends on the system defaults. Use getBytes("utf-8") or whatever. That eliminates ambiguity.

这篇关于尝试使用 AES 加密和解密字符串时出现 IllegalBlockSizeException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆