Encryption 使用aes 128 ctr部分解密Mega.co.nz文件以支持流媒体范围

Encryption 使用aes 128 ctr部分解密Mega.co.nz文件以支持流媒体范围,encryption,cryptography,streaming,aes,playready,Encryption,Cryptography,Streaming,Aes,Playready,如何从中间解密aes 128 ctr加密文件以支持http范围? 以下是加密文件: 密钥是base64加密的:E7VQWJ3CV1JUI5PKLIRTDQ9SRJT1HIQYGZPSPIIVP0 超级文件: IV通过解密密钥来计算,该密钥给出一个数组: Array ( [0] => 330649690 [1] => 1037877074 [2] => 1418435172 [3] => 2519395597 [4] => 2

如何从中间解密aes 128 ctr加密文件以支持http范围? 以下是加密文件:

密钥是base64加密的:E7VQWJ3CV1JUI5PKLIRTDQ9SRJT1HIQYGZPSPIIVP0

超级文件:

IV通过解密密钥来计算,该密钥给出一个数组:

Array
(
    [0] => 330649690
    [1] => 1037877074
    [2] => 1418435172
    [3] => 2519395597
    [4] => 257049755
    [5] => 1963858090
    [6] => 1645006666
    [7] => 2451723517
)
IV通过在长度为2的第4偏移处切片阵列获得,阵列的最后两个元素用0填充:

Array
(
    [0] => 257049755
    [1] => 1963858090
    [2] => 0
    [3] => 0
)
然后,该键被XOR'd并生成128位数组,然后php函数包将其转换为字符串:

 $key = array($key[0] ^ $key[4], $key[1] ^ $key[5], $key[2] ^ $key[6], $key[3] ^ $key[7]);
 $key = base64_encode(a32_to_str($key));
 $iv = base64_encode(a32_to_str($iv));
然后使用普通的php aes库对文件进行解密。我使用mcrypt_generic进行解密过程。 当我试图从第二字节或第三字节或中间字节解密文件时,问题就出现了。 如果我从第一个字节解密它,它可以正常工作

我注意到的另一件事是,如果我从第二个字节解密文件,但在此之前,我解密一个随机字符串或数字0,那么解密从第二个字节开始。 我想这与静脉阻塞计数器有关。我解密一个随机字节,然后继续解密实际的密码,使其工作。 我需要从一开始就开始解密文件,比如说从40mb偏移量开始解密,以支持实时strem搜索。 但这会消耗太多内存,因为我必须先解密40mb的0,然后才能进行查找。 如何将IV计数器值移动到40mb偏移

我读到,对于解密的每个块,IV增加+1。但由于我的IV是一个数组,我已经尝试了所有的方法,如果我在其中添加1,它将不起作用。 我已经做了好几个月了,都没有结果。请帮忙


这是我之前的问题,它有助于理解这个过程:

你最初的研究确实是正确的。在CTR模式下,每次加密操作后,IV或nonce简单地增加1。加密和解密在CTR模式下是相同的操作,因此您可以根据需要用一个字替换另一个字

换句话说,CTR模式密码的状态可以提前预测——只需将已加密的块数添加到初始IV中即可。特别是,该状态不以任何方式依赖于明文。AES的块大小为16,因此将加密的字节数除以16

可以将IV视为存储在big-endian中的128位整数。您使用的加密API将其表示为四个32位整数的数组。在初始化密码之前,只需将块数添加到第四个整数。如果您认为需要处理大约40亿个以上的块,则需要将溢出处理添加到第三个整数

稍微棘手的部分是将密码初始化为一种状态,在这种状态下,您已经加密了不能被块大小整除的字节数。解决方案是首先将密码初始化为已加密的字节数除以16,向下舍入,然后加密已加密的字节数mod 16伪字节。我相信这其实是你已经怀疑过的

您是用PHP编写的,但我发布了一个来自Mega downloader程序的方法,我用Java编写了该程序,以防它有所帮助:

公共密码getDownloadCipherfinal long startPosition引发异常{ 最终密码=Cipher.getInstanceAES/CTR/NoPadding; final ByteBuffer buffer=ByteBuffer.allocate16.putnoce; buffer.asLongBuffer.putstartPosition/16; cipher.initCipher.DECRYPT_模式,新SecretKeySpeckey,AES,新IvParameterSpecbuffer.array; 最终整数跳过=整数起始位置%16; 如果跳过!=0{ 如果cipher.updatenew字节[skip].length!=skip{ //这应该始终适用于CTR模式密码 throw new IOException未能从密码中跳过字节; } } 返回密码; } 本例中的nonce字段为8字节;这是问题中IV的两个非零整数。startPosition/16 long是另外两个整数。