我试图通过自己在这里寻找并在其他地方搜索很长一段时间来找到答案,但我仍然有一些问题。
假设这个 Java 代码:
try
{
int cipherMode = Cipher.ENCRYPT_MODE;
SecretKeySpec secretKey = ...; // generated previously using KeyGenerator
byte[] nonceAndCounter = new byte[16];
byte[] nonceBytes = ...; // generated previously using SecureRandom's nextBytes(8);
// use first 8 bytes as nonce
Arrays.fill(nonceAndCounter, (byte) 0);
System.arraycopy(nonceBytes, 0, nonceAndCounter, 0, 8);
IvParameterSpec ivSpec = new IvParameterSpec(nonceAndCounter);
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(cipherMode, secretKey, ivSpec);
File inFile = new File(...);
File outFile = new File(...);
long bytesRead = 0;
try (FileInputStream is = new FileInputStream(inFile);
FileOutputStream os = new FileOutputStream(outFile))
{
byte[] inBuf = new byte[512 * 1024];
byte[] outBuf = new byte[512 * 1024];
int readLen = 0;
ByteBuffer byteBuffer = ByteBuffer.allocate(8);
byteBuffer.putLong(bytesRead);
while ((readLen = is.read(inBuf)) != -1)
{
bytesRead += readLen;
cipher.update(inBuf, 0, readLen, outBuf, 0);
os.write(outBuf);
}
cipher.doFinal(outBuf, 0);
os.write(outBuf);
is.close();
os.close();
}
catch (Exception e) {
System.out.printf("Exception for file: %s\n", e);
}
}
catch (Exception e) {
System.out.printf("Exception: %s\n", e);
}
我的问题是:
关于 CTR 模式的计数器更新,上述代码是否被认为可以?具体来说,我自己不会更新计数器。我应该改用下面的 while 循环吗?我尝试了这个,因为我查看了 cipher.getIV() 在循环中返回的内容,但它没有改变,并且 getIV() 的描述也没有详细说明:
while ((readLen = is.read(inBuf)) != -1) { // use offset for last 8 bytes as counter byteBuffer.putLong(bytesRead); System.arraycopy(byteBuffer.array(), 0, nonceAndCounter, 8, 8); bytesRead += readLen; IvParameterSpec ivSpec = new IvParameterSpec(nonceAndCounter); cipher.init(cipherMode, secretKey, ivSpec); cipher.update(inBuf, 0, readLen, outBuf, 0); os.write(outBuf); }
我有更多与修改后的 while 循环方法相关的问题。以这种方式调用 cipher.init() 可以吗?我这样做是因为我还没有找到只更新 IV 的方法(实际上是计数器)。
这么大的块大小可以还是应该做得更小?在这种情况下,它应该有多大?