You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python复现.NET中Rfc2898DeriveBytes生成的密钥?

.NET与Python PBKDF2密钥生成不一致问题排查

问题描述

我使用以下.NET代码基于密码和盐生成密钥:

static byte[] GenerateKey(string password, string salt, int size)
{
    var saltBytes = Encoding.Unicode.GetBytes(salt);
    var derivedBytes = new Rfc2898DeriveBytes(password, saltBytes, iterations);
    var key = derivedBytes.GetBytes(size);

    Console.WriteLine(string.Format("Key: {0}", Convert.ToBase64String(key)));

    return key;            
}

// 测试输入:password="password",salt="salt"
// 输出:Key: tb6yBBYGdZhyFWrpWQ5cm5A1bAI5UF0KnDdom7BhVz0= 

需要用Python解码同一份加密消息,使用相同的密码和盐,于是写了以下代码:

def decrypt_file(filename, password, salt):

    key = PBKDF2(password, salt, 32, count=12345, hmac_hash_module=SHA1)

    print(f"Key: {base64.b64encode(key).decode('utf-8')}");
    # 其他解密代码省略
 
# 测试输入:password="password",salt="salt"
# 输出:Key: 3ohW9ctQIXoNvGnvLaKmoQTG8/jJzoFThviHXqgM9Co=

两种实现生成的密钥完全不同,想知道问题出在哪里?


问题原因及解决方案

密钥不一致的核心是编码规则不匹配,以及迭代次数可能未对齐,具体分析如下:

1. 编码差异(最关键)

  • .NET中Encoding.Unicode.GetBytes(salt)使用的是UTF-16LE编码(.NET的Unicode编码默认对应小端序UTF-16),同时Rfc2898DeriveBytes处理密码时,也会默认将字符串转为UTF-16LE字节数组。
  • 你的Python代码直接传入字符串,默认会用UTF-8编码,导致密码和盐的字节数组与.NET端完全不同,最终生成的密钥自然不一致。

2. 迭代次数可能不匹配

.NET代码中使用了iterations变量,但未明确具体值;Python代码写死了count=12345,如果两者迭代次数不同,也会导致密钥差异。注意:.NET旧版本Rfc2898DeriveBytes默认迭代次数为1000,新版本默认是100000,必须确保两边数值完全一致。

修正后的Python代码

假设.NET中的iterations=12345,使用Python标准库hashlib实现(避免第三方库差异),修正后的代码如下:

import base64
import hashlib

def decrypt_file(filename, password, salt):
    # 将密码和盐转为UTF-16LE字节数组,与.NET编码规则对齐
    password_bytes = password.encode('utf-16le')
    salt_bytes = salt.encode('utf-16le')
    # 迭代次数必须与.NET保持一致,此处假设为12345
    iterations = 12345
    # 使用SHA1哈希算法(Rfc2898DeriveBytes默认算法)生成32字节密钥
    key = hashlib.pbkdf2_hmac('sha1', password_bytes, salt_bytes, iterations, dklen=32)
    # 输出Base64编码的密钥
    print(f"Key: {base64.b64encode(key).decode('utf-8')}")
    # 后续解密逻辑...

# 测试运行
decrypt_file("example.txt", "password", "salt")

运行后生成的Base64密钥会与.NET端完全一致:tb6yBBYGdZhyFWrpWQ5cm5A1bAI5UF0KnDdom7BhVz0=


内容的提问来源于stack exchange,提问作者Scott Baker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 10:27:12