- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试编写一个 Python 模块来加密我们现有的 .NET 类可以解密的文本。据我所知,我的代码行向上但它没有解密(我在 C# 端收到“无效填充长度”错误)。我的 pkcs7 代码看起来不错,但研究表明无效的 key 可能会导致同样的问题。
这两种设置有何不同? python :
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
最佳答案
首先,我验证了 Rfc2898 和 PBKDF2 是同一个东西。然后,如上所述,问题似乎是 .net 主义。我在msdn上找到的
Rfc2898DeriveBytes 中 GetBytes 的实现在每次调用时都会发生变化,即。它保持状态。 (见页面中部的备注)
Python 示例(伪输出):
derived_key = PBKDF2(key, salt, 32, 1000)
iv = PBKDF2(key, salt, 16, 1000)
print(base64.b64encode(derived_key))
print(base64.b64encode(iv))
$123456789101112134==
$12345678==
.NET 中的相同(大概)代码(同样是伪输出):
var rfc = new Rfc2898DeriveBytes(key, saltBytes);
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);
}
Console.Writeline(Convert.ToBase64(cryptoProvider.Key));
Console.Writeline(Convert.ToBase64(cryptoProvider.IV));
$123456789101112134==
$600200300==
对 rfc.GetBytes 的后续调用总是会产生不同的结果。 MSDN 表示它在调用时混合了 key 大小。因此,如果您调用 GetBytes(20) 两次,则与调用 GetBytes(20+20) 或 GetBytes(40) 相同。从理论上讲,这应该只是增加 key 的大小,而不是完全改变它。
有一些解决方案可以解决这个问题,可以是在第一次调用时生成一个更长的 key ,然后将其分成派生 key 和 IV,或者随机生成一个 IV,将其附加到编码消息中,然后在解密之前将其剥离。
切片 python 输出产生与 .NET 相同的结果。它看起来像这样:
derived_key = PBKDF2(key, salt, 32, 1000)
iv = PBKDF2(key, salt, 32 + 16, 1000) # We need 16, but we're compensating for .NETs 'already called' awesomeness on the GetBytes method
split_key = iv[32:]
print(base64.b64encode(derived_key))
print(base64.b64encode(iv))
print(base64.b64encode(split_key))
$ 123456789101112134== # matches our derived key
$ 12345678== # doesn't match
$ 600200300== # matches. this is the base 64 encoded version of the tailing 16 bytes.
享受,
关于c# - PBKDF2 Python key 与 .NET Rfc2898,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26168544/
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 10年前关闭。 Improve this
我发现 IMAPv4 有一个缺点,因为它强制用户下载整个正文(文本/HTML + 附件)。 如何编写并提出 RFC 来解决该问题? 如果您之前有撰写技术文档、提案,尤其是 RFC 的经验,请分享。 最
URLComponents.init(url:resolvingAgainstBaseURL:) 的文档说: Returns the initialized URL components object
似乎 Internet-Draft 提供了一个下载 XML 文件的链接(例如 https://tools.ietf.org/id/draft-ietf-oauth-v2-31.xml ),但我找不到下
我注意到 RFC 中的一个错误,我想报告该错误,并希望看到发布的勘误表。 有谁知道如何向 IETF 工作组正式报告错误。 IETF 是否有某种错误/错别字跟踪? 我试图给 RFC 的作者发送一封电子邮
我看到http://www.ietf.org/rfc/rfc4122.txt RFC 4122 第 4 版的最大长度是多少?换句话说,它是否始终与从文档中获取的示例字符串值的最大长度相同? f81d4
rfc-editor说 "Obsoletes xxxx" refers to other RFCs that this one replaces. "Updates xxxx" refers to o
在原生 Android 日历应用中,使用 RFC 2445 协议(protocol)创建 .ics文件。我在一些博客中发现 RFC 2445 被 RFC 5545 取代。谁能告诉我 RFC 5545
我正在将一些 Python 代码翻译为 C++。部分代码使用base 64编码。 Python 代码使用RFC 3548编码,但我使用的C++库只有RFC 4648 . 我知道 RFC 4648 已过
我的程序在线抛出这个异常,我知道它出错的原因。 我的问题是如何找到错误的地方,Java 无法捕获此异常的位置。 如何获取有关此异常的其他信息,例如此错误的 API 请求地址。 错误信息如下: 2019
我正在尝试为 multipart/related 实现一个基本的 MIME 解析器。在 C++/Qt 中。 到目前为止,我一直在为 header 编写一些基本的解析器代码,并且我正在阅读 RFC 以了
我正在尝试在 HTTP 服务器上实现 RFC 2388 以支持多部分 POST。 我正在查看专门针对内容配置的“名称”参数的规范。 根据 RFC 2388 的第 3 节,它指出: Field name
首先,一些简单的背景知识...作为与第三方供应商集成的一部分,我有一个 C# .Net Web 应用程序,它接收一个 URL,其中包含查询字符串中的大量信息。该 URL 使用 MD5 哈希值和共享 k
早上好。 我们有一个使用 SAP RFC SDK 的“经典”API 的 SAP 工作 Idoc 接口(interface)。由于不再支持它,我们需要迁移到带有新 API 的新 Netweaver RF
我正在使用一个非常 bing 和旧的软件,它与 servlet 一起工作,并且在 URL 中包含重音符号和其他奇怪的字符。 几周前软件从JDK7升级到JDK11,服务器从Tomcat6升级到Tomca
1.情景展示 tomcat 日志时不时会报出如下异常信息,到底是怎么回事? ?
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid charact
谁能告诉我白天服务器的用途是什么?我提到了一些网站,如 wikipedia ,却找不到答案。 最佳答案 Daytime Protocol 是供计算机通信的一种广泛接受的已知格式 RFC 867允许 2
是否有关于在 RFC 上撰写评论的一般指南? 最佳答案 根据IETF ,一旦发布,RFC 不会改变。勘误可以提交到editor at rfc-editor.org .对未发表的 RFC 的评论可提交至
我写了一个ABAP功能模块,如果我用我的开发者账号执行它就可以了。 如果另一个用户执行它,他会得到一个空结果。另一个用户是无法使用 SAP GUI 登录的 RFC 帐户。 我不知道如何调试它。如何执行
我是一名优秀的程序员,十分优秀!