加密数据的随机访问 AES GCM 模式

3

这里有一个非常好的例子,演示了随机访问AES CTR模式并且它可以正常运行: Random access InputStream using AES CTR mode in android

private static final int AES_BLOCK_SIZE = 16;
private static IvParameterSpec calculateIVForOffset(final IvParameterSpec iv,
    final long blockOffset) {
final BigInteger ivBI = new BigInteger(1, iv.getIV());
final BigInteger ivForOffsetBI = ivBI.add(BigInteger.valueOf(blockOffset
        / AES_BLOCK_SIZE));

final byte[] ivForOffsetBA = ivForOffsetBI.toByteArray();
final IvParameterSpec ivForOffset;
if (ivForOffsetBA.length >= AES_BLOCK_SIZE) {
    ivForOffset = new IvParameterSpec(ivForOffsetBA, ivForOffsetBA.length - AES_BLOCK_SIZE,
            AES_BLOCK_SIZE);
} else {
    final byte[] ivForOffsetBASized = new byte[AES_BLOCK_SIZE];
    System.arraycopy(ivForOffsetBA, 0, ivForOffsetBASized, AES_BLOCK_SIZE
            - ivForOffsetBA.length, ivForOffsetBA.length);
    ivForOffset = new IvParameterSpec(ivForOffsetBASized);
}

return ivForOffset;
}

然而,在AES GCM模式下它不起作用。当我解密时,得到的是垃圾数据。我不是加密专家,已经试图破解了几天了。也许有人能够给出任何见解吗?我的猜测是需要以某种方式更改偏移量的IV计算,或者与认证标记有关(我没有使用)。

2个回答

4
GCM模式使用计数器模式进行保密。因此,在未经身份验证的情况下,有可能解密密文;可以参考我在这里的回答。要对给定的偏移量进行加密或解密,您可以更改计数器以更改给定偏移量的字节,并异或生成的密文。但是,如果跳过了单个字节,则无法验证任何密文。
因此,使用GCM最好将明文分成块并分别加密。请注意,您还应确保无法更改明文的顺序,例如通过使用HMAC或经过身份验证的Merkle树验证身份验证标记。

1

AES GCM使用一种称为GCTR的模式。它类似于CTR,但是定义得非常具体

当IV不是12字节时,首先对其进行哈希处理以获取12字节IV(GHASH函数被指定为与Galois域相同的单个乘法,该域用于MAC)。

然后将12字节IV与4字节计数器(从1开始)连接起来,以获得16字节的CTR块。

因此,像您在示例中所做的那样将IV视为BigInteger并递增它绝对行不通。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接