使用BouncyCastle的分组密码对字节数组进行加密/解密的最简单方法是什么? [英] What is the simplest way to encrypt/ decrypt a byte array using BouncyCastle's block cipher?

查看:180
本文介绍了使用BouncyCastle的分组密码对字节数组进行加密/解密的最简单方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个 BlockCipher 和一个 byte [] ,我是从获得的包含秘密消息的字符串,最简单的方法是获得 byte [] 个已加密消息的最简单方法?

If I have a BlockCipher and a byte[] that I got from a String containing a secret message, what's the easiest way to get a byte[] of the message encrypted?

在普通的Java API中,我可以执行 cipher.doFinal(secretMessage),但是这里似乎没有这样的东西,它

In the normal Java API, I could just do cipher.doFinal(secretMessage), but there doesn't seem to be anything like that here, it only processes blocks.

我知道我可以使用 BufferedBlockCipher ,但这仍然不能显着简化事情。

I know I can use a BufferedBlockCipher, but this still doesn't simplify things significantly. What's the easiest high-level way to use this cipher?

推荐答案

确定,因此,使用轻量级API和计数器模式是最简单的高级方法。您将获得的最简单和现代的模式之一:

OK, so using the lightweight API and counter mode, which is one of the easiest and modern modes you would get:

public class BouncyEncrypt {

    private static final int IV_SIZE = 16;

    public static void main(String[] args) throws Exception {
        // key should really consist of 16 random bytes
        byte[] keyData = new byte[256 / Byte.SIZE];
        KeyParameter key = new KeyParameter(keyData);

        byte[] ciphertext = encryptWithAES_CTR(key, "owlstead");
        System.out.println(decryptWithAES_CTR(key, ciphertext));
    }

    private static byte[] encryptWithAES_CTR(KeyParameter key, String in)
            throws IllegalArgumentException, UnsupportedEncodingException,
            DataLengthException {
        // iv should be unique for each encryption with the same key
        byte[] ivData = new byte[IV_SIZE];
        SecureRandom rng = new SecureRandom();
        rng.nextBytes(ivData);
        ParametersWithIV iv = new ParametersWithIV(key, ivData);

        SICBlockCipher aesCTR = new SICBlockCipher(new AESFastEngine());

        aesCTR.init(true, iv);
        byte[] plaintext = in.getBytes("UTF-8");
        byte[] ciphertext = new byte[ivData.length + plaintext.length];
        System.arraycopy(ivData, 0, ciphertext, 0, IV_SIZE);
        aesCTR.processBytes(plaintext, 0, plaintext.length, ciphertext, IV_SIZE);
        return ciphertext;
    }

    private static String decryptWithAES_CTR(KeyParameter key, byte[] ciphertext)
            throws IllegalArgumentException, UnsupportedEncodingException,
            DataLengthException {
        if (ciphertext.length < IV_SIZE) {
            throw new IllegalArgumentException("Ciphertext too short to contain IV");
        }

        ParametersWithIV iv = new ParametersWithIV(key, ciphertext, 0, IV_SIZE);

        SICBlockCipher aesCTR = new SICBlockCipher(new AESFastEngine());
        aesCTR.init(true, iv);
        byte[] plaintext = new byte[ciphertext.length - IV_SIZE];
        aesCTR.processBytes(ciphertext, IV_SIZE, plaintext.length, plaintext, 0);
        return new String(plaintext, "UTF-8");
    }
}

计数器模式不需要填充,并且完全在线,因此您只需要调用 processBytes 。对于CBC模式,您应该查看 PaddedBufferedBlockCipher 。在解密过程中,您仍然会有少量的缓冲区处理:在解密之前,您不知道填充的数量。

Counter mode does not require padding and is fully online, so you only have to call processBytes. For CBC mode you should look at PaddedBufferedBlockCipher. Still you would have slightly a tiny amount of buffer handling during decryption: before decryption you don't know the amount of padding that is present.

您可以删除IV代码和UTF-8字符解码+异常处理,但您可能会感到不安全,甚至可能不兼容。此代码将IV前缀为密文。

You could remove the IV code and the UTF-8 character decoding + exception handling, but you would be insecure and possibly incompatible. This code prefixes the IV to the ciphertext.

这篇关于使用BouncyCastle的分组密码对字节数组进行加密/解密的最简单方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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