gpt4 book ai didi

java - 在 AES-CTR 加密的输入中寻找

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:57:10 38 4
gpt4 key购买 nike

由于 CTR 模式下的 AES 非常适合随机访问,假设我有一个在 AES-CTR 模式下使用 CipherOutputStream 创建的数据源。下面的库(不是我的)使用 RandomAccessFile 允许查找文件中的特定字节偏移量。

我最初的想法是将 CipherInputStream 与使用正确参数初始化的 Cipher 一起使用,但是 the API for that不进行搜索并声明不支持markreset

是否有我错过的 API 的一部分可以为我做这件事,我是否应该查看 CTR 的 IV/block 计数器的配置并使用自定义输入流重新创建它(听起来像霰弹枪瞄准 self 给我)还是采用我错过的其他方法?

最佳答案

我最后查了一下 IV 在 CTR 模式下是如何更新的。事实证明,这会为其处理的每个 AES block 执行一个简单的 +1。我按照以下几行实现了阅读。

给定一个实现类似read 的方法的类,该方法将读取加密的字节序列中的下一个字节,并且需要支持在该序列和以下变量中查找:

  • BLOCK_SIZE:固定为16(128位,AES block 大小);
  • cipher:javax.crypto.Cipher实例,初始化处理AES;
  • delegate:一个java.io.InputStream,它包装了一个允许随机访问的加密资源;
  • input:一个 javax.crypto.CipherInputStream 我们将从中读取(流将负责解密)。

seek 方法是这样实现的:

void seek(long pos) {
// calculate the block number that contains the byte we need to seek to
long block = pos / BLOCK_SIZE;
// allocate a 16-byte buffer
ByteBuffer buffer = ByteBuffer.allocate(BLOCK_SIZE);
// fill the first 12 bytes with the original IV (the iv minus the actual counter value)
buffer.put(cipher.getIV(), 0, BLOCK_SIZE - 4);
// set the counter of the IV to the calculated block index + 1 (counter starts at 1)
buffer.putInt(block + 1);
IvParameterSpec iv = new IvParameterSpec(buffer.array());
// re-init the Cipher instance with the new IV
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
// seek the delegate wrapper (like seek() in a RandomAccessFile and
// recreate the delegate stream to read from the new location)
// recreate the input stream we're serving reads from
input = new CipherInputStream(delegate, cipher);
// next read will be at the block boundary, need to skip some bytes to arrive at pos
int toSkip = (int) (pos % BLOCK_SIZE);
byte[] garbage = new byte[toSkip];
// read bytes into a garbage array for as long as we need (should be max BLOCK_SIZE
// bytes
int skipped = input.read(garbage, 0, toSkip);
while (skipped < toSkip) {
skipped += input.read(garbage, 0, toSkip - skipped);
}

// at this point, the CipherStream is positioned at pos, next read will serve the
// plain byte at pos
}

请注意,此处省略了寻找委托(delegate)资源,因为这取决于委托(delegate) InputStream 下的内容。另请注意,初始 IV 需要从计数器 1(最后 4 个字节)开始。

单元测试表明这种方法有效(性能基准将在未来的某个时候完成:))。

关于java - 在 AES-CTR 加密的输入中寻找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16582238/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com