使用BouncyCastle的分组密码对字节数组进行加密/解密的最简单方法是什么? [英] What is the simplest way to encrypt/ decrypt a byte array using BouncyCastle's block cipher?
问题描述
如果我有一个 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屋!