如果我有一个BlockCipher和一个byte[],它们是从包含秘密消息的String中获得的,最简单的方法是将消息的byte[]加密吗?

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

我知道我可以使用BufferedBlockCipher,但这仍然不能显着简化事情。使用此密码的最简单的高级方法是什么?

最佳答案

好的,因此使用轻量级的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前缀为密文。

关于java - 使用BouncyCaSTLe的分组密码对字节数组进行加密/解密的最简单方法是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30511903/

10-10 10:41