好的,所以使用轻量级 API 和计数器模式,这是您将获得的最简单和现代的模式之一:
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。在解密过程中,您仍然需要处理少量的缓冲区:在解密之前,您不知道存在的填充量。
您可以删除 IV 代码和 UTF-8 字符解码 + 异常处理,但您会不安全并且可能不兼容。此代码将 IV 作为密文的前缀。