【问题标题】:OutputLengthException in Rijndael impletationRijndael 实现中的输出长度异常
【发布时间】:2019-08-19 12:30:31
【问题描述】:

我在使用 BouncyCastle API for Java 实现 Rijndael 加密时遇到问题。

当我执行cipher.doFinal(inputTextBytes, intOutOff); 时,我得到了OutputLengthException

org.bouncycastle.crypto.OutputLengthException: 输出缓冲区太短

我不完全理解如何生成该整数来执行doFinal() 方法。

这是我尝试过的:

public class RijndaelAndRFC2899Implementation {

    final static String WORD = "763059";
    final static String PASSWORD = "515t3ma5m15B4d35";
    final static byte[] SALT = new byte[]{1, 2, 3, 4, 5, 6, 7, 8};
    final static int KEY_SIZE = 256;
    final static int BLOCK_SIZE = 128;
    final static int ITERATIONS = 1000;

    public static void main(String[] args) throws Exception {
        BufferedBlockCipher cipher = getCipher(PASSWORD, true);
        byte[] inputText = WORD.getBytes("UTF-8");
        byte asd[] = new byte[cipher.getOutputSize(inputText.length)];
        int l = cipher.processBytes(inputText, 0, inputText.length, asd, 0);
        int n = cipher.doFinal(inputText, l); //<---HERE PRODUCES OutputLengthException
    }

    private static BufferedBlockCipher getCipher(String password, boolean encrypt) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(password.getBytes("UTF-8"));
        byte[] newPassword = md.digest();

        PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator();
        generator.init(newPassword, SALT, ITERATIONS);

        ParametersWithIV iv = ((ParametersWithIV) generator.generateDerivedParameters(KEY_SIZE, BLOCK_SIZE));

        RijndaelEngine engine = new RijndaelEngine();
        BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(engine));   
        cipher.init(encrypt, iv);

        return cipher;
    }

}

你能帮我理解我做错了什么吗?

【问题讨论】:

    标签: java encryption bouncycastle rijndael block-cipher


    【解决方案1】:

    doFinal() 的调用应该将输出数组作为第一个参数 - 而不是您正在处理的输入:

    public static void main(String[] args) throws Exception {
        BufferedBlockCipher cipher = getCipher(PASSWORD, true);
        byte[] inputText = WORD.getBytes("UTF-8");
        byte asd[] = new byte[cipher.getOutputSize(inputText.length)];
        int l = cipher.processBytes(inputText, 0, inputText.length, asd, 0);
        int n = cipher.doFinal(asd, l); // <--- Change to asd
    }
    

    (我还没有验证其余的实现!)

    【讨论】:

    • 还要注意doFinal('n')的返回值;根据密码算法,getOutputSize 可能高估了实际输出大小,因此输出可能没有完全填满输出缓冲区('asd')。返回值是增量输出长度,因此您可能还需要“int n = l + cipher.doFinal(asd, l);”而是。
    猜你喜欢
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-21
    相关资源
    最近更新 更多