AES265 Python到C#的转换失败

AES265 Python到C#的转换失败,python,c#,cryptography,Python,C#,Cryptography,我正在尝试将几行Python代码转换为C代码。我正面临一个错误,我不知道哪一行导致了这个错误。我对Python一点都不了解。我想我犯了一个错误,将子数组切片或解密过程,然后用不同的方法重写,例如Buffer.BlockCopy,但没有运气 C#代码 编辑: 图像文件已成功创建,但由于格式不正确或不受支持,任何图像查看器都无法打开。正如Artjom B所指出的,在确定MAC时,C代码中存在一个错误,同时已在发布的代码中修复 但是,将密钥大小显式设置为256位或将块大小显式设置为128位没有区

我正在尝试将几行
Python
代码转换为
C
代码。我正面临一个错误,我不知道哪一行导致了这个错误。我对Python一点都不了解。我想我犯了一个错误,将子数组切片或解密过程,然后用不同的方法重写,例如
Buffer.BlockCopy
,但没有运气

C#代码

编辑:
图像文件已成功创建,但由于格式不正确或不受支持,任何图像查看器都无法打开。

正如Artjom B所指出的,在确定MAC时,C代码中存在一个错误,同时已在发布的代码中修复

但是,将密钥大小显式设置为256位或将块大小显式设置为128位没有区别,因为默认情况下,
RijndaelManaged
使用这些值。这与AES相对应,因此也可以应用,例如
AES管理

除了MAC确定中的错误外,C代码中还有两个错误:

  • Python代码与C#代码的对应部分是:

    var mediaKeyExtracted=hkdf.Extract(mediakey,null);
    var mediaKeyExpanded=hkdf.Expand(mediaKeyExtracted,112,salt);
    
    这将为
    mediaKeyExpanded
    返回一个值,该值对应于Python代码中确定的值,即(十六进制编码):

    A02B98BD6CE9575C95CC938E39BB782BA5D6478C98C0E356EA7EE70B4900F3861DB9528CD4490CA02789410B3C3AB4489EBCCECECEC2C153A015F213A331D147BA515450ED55F8FF03D8FCE4760825351F16B223D371E30846C0492E259CAB263D63BC6E098280002CB125FC807A03A2B
    
    它给出了以下值

    iv:a02b98bd6ce9575c95cc938e39bb782b
    密码匙:a5d6478c98c0e356ea7ee70b4900f3861db9528cd4490ca02789410b3c3aba44
    麦基:89ebcce2c153a015f213a331d147ba515450edd55f8ff03d8fce4760825351f1
    
    请注意,名为
    salt
    的变量实际上不是salt,而是info参数(请参见第2节)

  • 根据Python代码,即函数,可以确定Python代码使用PKCS7填充。因此,必须在C#代码中应用PKCS7填充,而不是零填充,否则不会删除加密中的PKCS7填充:

    rijndaelManaged.Padding = PaddingMode.PKCS7;
    
    请注意,PKCS7实际上不需要显式指定,因为它是默认值。但是,您必须删除显式指定零填充的行

通过这些更改,可以使用mediaKey
udot3mfvt3kmp0+MAybMlgVrnEyVAdxSamXQ+qbRog=
和带有C代码的appInfo
WhatsApp图像密钥来解密(另请参见)。解密文件的内容与使用Python代码解密的文件相同


顺便说一下:使用C代码中的变量
file
iv
macKey
mac
,可以根据以下说明验证文件(请参阅):

HMACSHA256 hmac = new HMACSHA256(macKey);

byte[] ivFile = new byte[iv.Length + file.Length];
Array.Copy(iv, 0, ivFile, 0, iv.Length);
Array.Copy(file, 0, ivFile, iv.Length, file.Length);

byte[] macCalc = hmac.ComputeHash(ivFile);

byte[] macCalc10 = new byte[10];
Array.Copy(macCalc, 0, macCalc10, 0, 10);

bool verified =  macCalc10.SequenceEqual(mac);

由于要验证的文件以及生成密钥(
cipherKey
macKey
)和IV的数据都是从同一个位置下载的(作为rar文件,请参见),这是一个相当低的保护。

我建议您使用
动态
而不是使用
var
。这将使代码非常接近python的使用。
mediaData.Skip(10)
应该是
mediaData.Skip(length-10)
,但这并不能解决您的问题。确保RijndaelManaged的块大小为128。此外,填充可能会有所不同。您是否使用(十六进制)编辑器查看结果文件以查看是否存在差异?我已经编辑了我的问题。仍然不起作用Python代码中的
AESUnpad()
对应物(即
AESPad()
)使用PKCS7填充(),因此正如Artjom B.已经怀疑的那样,与C代码中使用零填充的填充不同。我还将检查Python代码中的
HKDF()
和C代码中的
HKDF.Expand()
是否给出相同的结果,即
mediaKeyExpanded
在两个代码中是否相同(以验证两者在功能上相同)。更改为
PKCS7
会给我
填充无效且无法删除

rijndaelManaged.Padding = PaddingMode.PKCS7;
HMACSHA256 hmac = new HMACSHA256(macKey);

byte[] ivFile = new byte[iv.Length + file.Length];
Array.Copy(iv, 0, ivFile, 0, iv.Length);
Array.Copy(file, 0, ivFile, iv.Length, file.Length);

byte[] macCalc = hmac.ComputeHash(ivFile);

byte[] macCalc10 = new byte[10];
Array.Copy(macCalc, 0, macCalc10, 0, 10);

bool verified =  macCalc10.SequenceEqual(mac);