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

2023-12-29

我手头上有一个问题,需要解密 AES 加密的密文,其规范如下 密文由以下部分组成: · 256 字节的 RFC2898 派生盐,后跟使用密码、“密码”和派生 IV 进行 AES 加密的消息。 示例消息是“这是我的秘密字符串,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());
        }

输出是:“这是我的秘密字符串,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”

预期输出:“这是我的秘密字符串,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 调用.

请给我一些对此有用的指导。

谢谢, 穆尔


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 密钥和 16 字节 IV。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# RFC2898DeriveBytes 正在工作,但 Python PBKDF2 生成的密钥和 IV 不适用于 Python AES 解密 的相关文章

  • 如何在Python Selenium中获取WebElement的类名?

    我使用 Selenium WebDriver 来抓取从网页中获取的 用 JavaScript 编写的表格 我正在迭代表行列表 每行可能属于不同的类别 我想获取此类的名称 以便我可以为每一行选择适当的操作 table body table f
  • 打开位置设置页面或提示用户启用位置

    我一直在绞尽脑汁 徒劳地谷歌搜索 我正在尝试找到一种方法来提示用户通过直接进入设置页面或仅点击屏幕上的 是 来切换位置 我见过的所有代码似乎都不起作用 有人有有效的方法吗 一个详细的例子将不胜感激 谢谢 我对 Xamarin 开发非常陌生
  • += 运算符在 C++ 中是如何实现的?

    这是我一直在思考的一个问题 但从未找到任何资源来说明这个问题的答案 事实上它不仅是为了 也适用于它的兄弟姐妹 即 等等 当然不是 考虑这个例子 int a 5 a 4 this will make a 9 现在考虑等效表达式 a a 4 T
  • 根据 Active Directory 策略检查密码[重复]

    这个问题在这里已经有答案了 我有一个允许用户更改其 AD 密码的前端 有没有办法获取特定用户及其属性 长度 复杂性 的密码策略 例如细粒度 有没有办法根据此特定策略检查字符串 xyz121 编辑 我不想检查活动目录中存储的当前密码 我想检查
  • 使用 catch all 字典属性将 json 序列化为对象

    我想使用 JSON net 反序列化为对象 但将未映射的属性放入字典属性中 是否可以 例如给定 json one 1 two 2 three 3 和 C 类 public class Mapped public int One get se
  • 原子的 C++ 内存屏障

    在这方面我是个新手 谁能提供以下内存屏障之间差异的简化解释 窗户MemoryBarrier 围栏 mm mfence 内联汇编asm volatile memory 内在的 ReadWriteBarrier 如果没有简单的解释 一些好文章或
  • 重定向 std::cout

    我需要一个类 在其对象的生命周期内将一个 ostream 重定向到另一个 ostream 经过一番修补后 我想出了这个 include
  • 确定相关词的编程方式?

    使用网络服务或软件库 我希望能够识别与词根相关的单词 例如 座位 和 安全带 共享词根 座位 但 西雅图 不会被视为匹配 简单的字符串比较对于这类事情似乎是不可行的 除了定义我自己的字典之外 是否有任何库或 Web 服务不仅可以返回单词定义
  • 使用 python 将多个 JSON 文件插入 MongoDB

    JSON文件如下a json b json z json 26个json文件 每个文件的 json 格式如下 a cappella word a cappella wordset id 5feb6f679a meanings id 4920
  • 如何解决文件被另一个进程使用的问题?

    我一直在 VS NET 2010 中调试 没有任何问题 但现在无法建造 我收到错误 Unable to copy file filename to bin Debug filename The process cannot access t
  • 如何使用 python 在 XML 声明后添加注释

    import xml etree ElementTree as ET def addCommentInXml fileXml C Users Documents config xml tree ET parse fileXml root t
  • XCode std::thread C++

    对于学校的一个小项目 我需要创建一个简单的客户端 服务器结构 它将在路由器上运行 使用 openWRT 并且我试图在这个应用程序中使用线程做一些事情 我的 C 技能非常有限 所以我在internet https stackoverflow
  • 如何在 SQLite 中检查数据库是否存在 C#

    我目前正在用 C 编写一个应用程序 并使用 sqlite 作为嵌入式数据库 我的应用程序在启动时创建一个新数据库 但如何让它检查数据库是否存在 如果它确实存在 我如何让它使用它 如果不存在如何创建一个新数据库 这是我到目前为止所拥有的 pr
  • DataFrame 对象没有属性“sort_values”

    dataset pd read csv dataset csv fillna 100 dataset Id 0 dataset i 0 dataset j 0 entries dataset dataset Id 0 print type
  • 仅将唯一行插入 SQLite (python)

    我在用着cursor executemany将 CSV 文件中的批量行插入到 SQLite 表中 根据主键字段 其中一些行预计会重复 当我执行该命令时 可以预见的是 我会收到完整性错误 并且不会插入任何内容 如何有选择地仅插入非重复行 而无
  • 如何使用“路径”查询 XDocument?

    我想查询一个XDocument给定路径的对象 例如 path to element I want 但我不知道如何继续 您可以使用以下方法System Xml XPath Extensions http msdn microsoft com
  • 在Python中设置Windows命令行终端标题

    我在 Windows 计算机上运行某个 Python 脚本的多个实例 每个实例都来自不同的目录并使用单独的 shell 窗口 不幸的是 Windows 为每个 shell 窗口提供了相同的名称
  • 检查另一种形式的线程是否仍在运行

    我有一个涉及两个窗体的 Windows 窗体应用程序 子表单用于将数据导出到 CSV 文件 并使用后台工作者写入文件 当这种情况发生时 我隐藏了表格 当后台工作程序运行时 父窗体仍然处于活动状态 因此即使后台工作程序正在写入文件 用户也可以
  • 与仅调用依赖函数/类相比,在 FastAPI 中使用 Depends 有哪些优点?

    FastAPI 提供了way https fastapi tiangolo com tutorial dependencies 通过其自己的依赖关系解析机制来管理依赖关系 例如数据库连接 它类似于一个pytest夹具系统 简而言之 您在函数
  • 如何创建实体集或模型而不在数据库中创建相应的表 - 实体框架

    我的 sqlserver 数据库中有一个存储过程 它返回多个结果集 我正在使用 msdn 中的以下链接从实体框架中的 SP 读取多个结果集 https msdn microsoft com en us library jj691402 v

随机推荐