Java密码更新方法

时间:2014-08-01 19:09:53

标签: java encryption

我正在尝试用Java学习编码并坚持使用Cipher.update()方法。它是否有一些可以更新的最大数据长度? 这是我所说的一个例子(我把“String s”值仅用于加速过程,这个值通过加密和解密过程):

public class AES {
    public static String s = "long string";

    public byte [] encryptAES(byte[] data, byte[] keyPass) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {

        Cipher ciph = Cipher.getInstance("AES");

        SecretKeySpec AESkeySpec = new SecretKeySpec(keyPass, "AES");
        ciph.init(ENCRYPT_MODE,AESkeySpec);

        ciph.update(s.getBytes());
        byte[] encryptedData = ciph.doFinal();

        return encryptedData;
    }
}

解密后的输出:long string

如果我改变了价值

public static String s = "long long long long long long long long long long long string";
解码后的

输出为:g long string

如果在我取出.update()方法并执行加密之后

Cipher ciph = Cipher.getInstance("AES");

SecretKeySpec AESkeySpec = new SecretKeySpec(keyPass, "AES");
ciph.init(ENCRYPT_MODE,AESkeySpec);
//ciph.update(s.getBytes());

byte[] encryptedData = ciph.doFinal(s.getBytes());
return encryptedData;

我会得到预期的输出,例如:long long long long long long long long long long long string

为什么会这样?

3 个答案:

答案 0 :(得分:3)

update方法返回加密块。但是我看到你只从doFinal获取密文。您应该使用updatedoFinal中的所有块来完成加密的块流。

注意:您正在使用ECB模式,这意味着每个块都是独立加密的,它的安全性较低,只有在您知道自己在做什么时才能使用。这就是为什么你能够解密最后一个块(AES的16个字节)并看到截断的明文。更多信息:http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

答案 1 :(得分:2)

对于ECB和CBC modes of operation,明文的每个块(128位或16个字节,用于AES)或者一旦可用就会被加密。此外,您的示例使用PKCS#7 padding(或者,在Java中,"PKCS5Padding")来确保将最后一个明文填充到完整块。否则你将无法加密它。

加密时,缓冲所有生成的密文显然不是一个好主意。因此,update只会返回可以加密的所有块。因此,您将始终获得多个块大小。这意味着可能将块的一部分保留在内部缓冲区中。当然,一旦为完整块添加了足够的字节,它将加密并返回数据。所有这些意味着更新可能会比输入更多或更少地返回blocksize - 1个字节。对于较小的输入,它可能根本不返回任何内容 - 所有内容都被缓冲,直到块已满。

现在PKCS#7填充总是应用,将1加到块大小的字节。显然,在应用填充之前,密码必须知道是否需要更多字节,或者是否达到了明文的结尾。因此doFinal将返回至少一个块,即使没有数据呈现给它。如果先前的更新未返回任何数据,则doFinal()方法将返回整个密文。

或多或少可以执行相同的解释推理。另请注意getOutputSize(int inputLength)getBlockSize()Cipher方法。如果要立即接收所有数据,可以使用流密码操作模式,例如"AES/CTR/NoPadding",其块大小为1个字节。


虽然这可以解释实际问题,但您问的问题是“它是否有一些可以更新的最大数据长度?”。答案是更新仅受JVM中可用内存量和Java中字节数组大小的限制。

答案 2 :(得分:-1)

cipher.update()返回为该明文生成的密文。

如果忽略该密文,您将无法对其进行解密。