【发布时间】:2014-11-27 21:33:02
【问题描述】:
我正在尝试编写一个 Python 模块来加密我们现有的 .NET 类可以解密的文本。据我所知,我的代码行向上但没有解密(我在 C# 端收到“无效填充长度”错误)。我的 pkcs7 代码看起来不错,但研究表明无效的密钥可能会导致同样的问题。
这两种设置有什么不同? 蟒蛇:
derived_key = PBKDF2(crm_key, salt, 256 / 8, iterations)
iv = PBKDF2(crm_key, salt, 128 / 8, iterations)
encoder = pkcs7.PKCS7Encoder()
cipher = AES.new(derived_key, AES.MODE_CBC, iv)
decoded = cipher.decrypt(encoded_secret)
#encode - just stepped so i could debug.
padded_secret = encoder.encode(secret) # 1
encodedtext = cipher.encrypt(padded_secret) # 2
based_secret = base64.b64encode(encodedtext) # 3
我认为 based_secret 可以传递到 C# 并在那里解码。但它失败了。同样的加密c#代码是:
var rfc = new Rfc2898DeriveBytes(key, saltBytes);
// create provider & encryptor
using (var cryptoProvider = new AesManaged())
{
// Set cryptoProvider parameters
cryptoProvider.BlockSize = cryptoProvider.LegalBlockSizes[0].MaxSize;
cryptoProvider.KeySize = cryptoProvider.LegalKeySizes[0].MaxSize;
cryptoProvider.Key = rfc.GetBytes(cryptoProvider.KeySize / 8);
cryptoProvider.IV = rfc.GetBytes(cryptoProvider.BlockSize / 8);
using (var encryptor = cryptoProvider.CreateEncryptor())
{
// Create a MemoryStream.
using (var memoryStream = new MemoryStream())
{
// Create a CryptoStream using the MemoryStream and the encryptor.
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
// Convert the passed string to a byte array.
var valueBytes = Encoding.UTF8.GetBytes(plainValue);
// Write the byte array to the crypto stream and flush it.
cryptoStream.Write(valueBytes, 0, valueBytes.Length);
cryptoStream.FlushFinalBlock();
// Get an array of bytes from the
// MemoryStream that holds the
// encrypted data.
var encryptBytes = memoryStream.ToArray();
// Close the streams.
cryptoStream.Close();
memoryStream.Close();
// Return the encrypted buffer.
return Convert.ToBase64String(encryptBytes);
}
}
}
我正在使用的 Python pkcs7 实现是: https://gist.github.com/chrix2/4171336
【问题讨论】:
-
我首先尝试检查生成的密钥在 C# 和 Python 中是否相同。
-
C# 的关键输出是一个字节数组,它在 Python 中是一个 UTF-8 字符串。为了正确比较这些,我可以 Convert.ToBase64(csharpKey) 和 base64.encode(pythonkey) 吗?这应该让我得到可比较的项目吗?
-
经过大量研究后,我发现了一些有用的东西: Rfc2898DeriveBytes.GetBytes 的初始实例和对 PBKDF2 的调用产生了相同的密钥。但是,根据 MSDN,GetBytes 正在复合调用以生成新密钥。我第二次调用 GetBytes(获取 IV)时,它的输出完全不同。
-
哎呀,真不敢相信我错过了那个,除了 NullUserException 的评论之外没有进一步阅读。是的,如果您执行两次
GetBytes,您将只获得更多字节的 PBKDF2 生成的 stream。如果你在PasswordDeriveBytes上这样做,你会得到完全的陷阱,但这完全是另一个问题。最好将其发布为您自己问题的答案,很高兴您解决了问题。
标签: c# python encryption aes pbkdf2