gpt4 book ai didi

C# RFC2898DeriveBytes 正在工作,但 Python PBKDF2 生成的 key 和 IV 不适用于 Python AES 解密

转载 作者:太空宇宙 更新时间:2023-11-03 14:37:34 25 4
gpt4 key购买 nike

我手头上有一个问题,无法解密 AES 加密密文,其规范如下密文由以下部分组成:· 256 字节的 RFC2898 派生盐,后跟使用密码、“密码”和派生 IV 进行 AES 加密的消息。示例消息是“这是我的 secret 字符串,lorem ipsum”,密码是使用 C# 代码加密的“password”此消息可以使用以下 C# 代码正常解密

private static readonly int SALT_SIZE = 256;
public static void Decrytor(){
// Encrypted Message
var cipherText = "i+EKwmlAF0VYh4GwDd+bGf3+yreYsPJW2Oq/w9FXjsp7RI3VqRiqtnqiAD4n6U0JJSTe2ct4B7lgrG+dHxeGcXYEYIERXvU0xnUdH+z3mRwmgYOqCU9HRUKy/z3GKISTm8qH030KTYm3YMBjnKpU8gaRcoDPP/nCiB3o5fPdyspgJgT/qt5BuvwYq7n0qg6ez/Wi4447gq/qHwG3wuuYLSBUCfmIkgGaO1KXqv3SsR8EAhrmMBmPDJfjc3sydNqs5B8J9/JvZFEZULTb8rLQZKQvgHhH9/53Bzs3zmoq0RFbgSueUbyeWb9rLAzYieTz8Yj0srG4GtwPrTPoItc6/hvx5stZ6pX8tgyk9Y3baT0JFMtGgxve7yduy8idTCQdAwRc5NOo4+CBk7P/sIw6+Q==";
var key = "password";
// Extract the salt from our cipherText
var allTheBytes = Convert.FromBase64String(cipherText);
var saltBytes = allTheBytes.Take(SALT_SIZE).ToArray();
var cipherTextBytes = allTheBytes.Skip(SALT_SIZE).Take(allTheBytes.Length - SALT_SIZE).ToArray();

var keyDerivationFunction = new Rfc2898DeriveBytes(key, saltBytes);
// Derive the previous IV from the Key and Salt
var keyBytes = keyDerivationFunction.GetBytes(32);
var ivBytes = keyDerivationFunction.GetBytes(16);

// Create a decrytor to perform the stream transform.
// Create the streams used for decryption.
// The default Cipher Mode is CBC and the Padding is PKCS7 which are both good
var aesManaged = new AesManaged();
var decryptor = aesManaged.CreateDecryptor(keyBytes, ivBytes);
var memoryStream = new MemoryStream(cipherTextBytes);
var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
var streamReader = new StreamReader(cryptoStream);

// Return the decrypted bytes from the decrypting stream.
Console.WriteLine("\n{0}\n", streamReader.ReadToEnd());
}

输出为:“这是我的 secret 字符串,lorem ipsum”

但是当我尝试按照 Python2.7 等效实现解密消息时,它没有正确解密前几个字符

import base64
from Crypto.Cipher import AES
from Crypto.Protocol import KDF

def p_decrypt( self, text ):
text_dec = base64.b64decode(text)
salt = text_dec[:256]
enc_txt = text_dec[256:]
key_bytes = KDF.PBKDF2(self.key, salt, dkLen=32)
iv = KDF.PBKDF2(self.key, salt)
cipher = AES.new(key_bytes, AES.MODE_CBC, iv)
return cipher.decrypt(enc_txt)

输出为:“�增��”j�����“t string, lorem ipsum”

预期输出:“这是我的 secret 字符串,lorem ipsum”

当我使用 C# RFC2898DeriveBytes 方法生成的 keyBytes 和 IV 时,我试图找到问题,该方法也可以正常使用 python 代码,但 python 代码没有使用 PBKDF2 正确解密整个消息生成 keyBytes 和 IV。

C# RFC2898DeriveBytes 和 python PBKDF2 都使用 HMACSHA1 哈希算法生成 keyByte,但 C# RFC2898DeriveBytes 方法生成不同的 keyBytes 和 IV,而 Python PBKDF2 返回生成的 keyBytes 的前 16 个字节用于 IV 调用。 p>

请给我一些有用的指导。

谢谢,穆尔

最佳答案

Rfc2898DeriveBytes 是一个流响应对象,因此连接两个连续的调用与将两个长度加在一起进行一次调用相同。

var pbkdf2WithTwoCalls = new Rfc2898DeriveBytes(...)
var pbkdf2WithOneCall = new Rfc2898DeriveBytes(sameParametersAsAbove);

byte[] twoCallA = pbkdf2WithTwoCalls.GetBytes(32);
byte[] twoCallB = pbkdf2WithTwoCalls.GetBytes(16);

byte[] oneCall = pbkdf2WithOneCall.GetBytes(32 + 16);

if (!oneCall.SequenceEquals(twoCallA.Concat(twoCallB))
throw new TheUniverseMakesNoSenseException();

因此,Python 中的解决方案是对 PBKDF2 进行一次 48 字节调用,然后将其拆分为 32 字节 AES key 和 16 字节 IV。

您的解密响应表明 key 正确,但 IV 不正确。

关于C# RFC2898DeriveBytes 正在工作,但 Python PBKDF2 生成的 key 和 IV 不适用于 Python AES 解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46821018/

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