使用c#中的Rfc2898DeriveBytes和go中的pbkdf2生成相同的密钥

使用c#中的Rfc2898DeriveBytes和go中的pbkdf2生成相同的密钥,c#,go,pbkdf2,C#,Go,Pbkdf2,为什么C#中的Rfc2898DeriveBytes和go lang中的pbkdf2会生成不同的密钥 我的C#代码 使用系统; 使用System.Security.Cryptography; 使用系统文本; 公开课考试 { 专用静态字节[]passBytes=新字节[] {164,176,124,62,244,154,226,211,177,90,202,180,12,142,25,225}; 专用静态字节[]saltBytes=新字节[] {173,205,190,172,239,190,242

为什么C#中的
Rfc2898DeriveBytes
和go lang中的
pbkdf2
会生成不同的密钥

我的C#代码

使用系统;
使用System.Security.Cryptography;
使用系统文本;
公开课考试
{
专用静态字节[]passBytes=新字节[]
{164,176,124,62,244,154,226,211,177,90,202,180,12,142,25,225};
专用静态字节[]saltBytes=新字节[]
{173,205,190,172,239,190,242,63,219,205,173,196,218,171,142,214};
公共静态字节[]GetKey()
{
var key=newrfc2898derivebytes(Encoding.UTF8.GetString(passBytes,0,16),saltBytes.GetBytes(16);
返回键;
}
公共静态void Main()
{
System.Console.WriteLine(Convert.ToBase64String(GetKey());
}
}
输出:77U85CphtSEwPP9a2T/jaQ==


戈朗码

主程序包
进口(
b64“编码/基本64”
“golang.org/x/crypto/pbkdf2”
“加密/sha1”
)
变量(
pass[]byte=[]字节{164176124,62244154226211177,90202180,12142,25225}
salt[]字节=[]字节{173205190172239190242,63219205173196218171142214}
)
func getKey()(键[]字节){
key=pbkdf2.key(通过,salt,1000,16,sha1.新)
返回
}
func main(){
打印(b64.StdEncoding.EncodeToString(getKey()))
}
输出:hnuuu+he4aF7vAzA8rfQtw==


我必须做些不同的事情吗?

在初始化C#实例时,您使用的是不同的变量(接受UTF-8
字符串的构造函数)。此外,正如zaph所指出的,您需要对C#和
golang
代码使用相同的迭代计数。
golang
版本使用
[]字节
参数作为密码和salt,而C#对应的是


上述代码的输出与
golang
版本相同。

它们是否都使用相同的迭代计数和SHA1?另外,在
passBytes
上使用
UTF8
似乎是可疑的,因为
passBytes
可能不是有效的UTF-8字符串。获取字符串的Rfc2898DeriveBytes构造函数只是通过UTF-8编码立即将其转换为字节。通过直接将字节传递给基于字节[]的ctor,可以跳过字符串的创建。@bartonjs c代码中有什么错误?是不是
Encoding.UTF8.GetString(passBytes,0,16)
不是应该在
passBytes
上使用的正确编码?@avut我的观点是,你有字节,你可以将它们转换成字符串(通过UTF8),你可以将它们传递给构造函数,然后将字符串转换成字节(通过UTF8)。只需使用一个直接获取字节的构造函数就可以节省工作。@bartonjs好吧!我明白你的意思。但是为什么输出是不同的呢?是什么使输出不同。C中的默认编码不是UTF-16吗?所以将字符串转换为UTF-8应该得到相同的输出?我很困惑,谢谢你的回复。如果我需要在golang???@AV中复制C代码,这取决于您要复制哪个C功能。如果在C#构造函数中没有指定迭代,我认为默认值将是1000。但是,有些C#构造函数使用随机salt(
Rfc2898DeriveBytes(String,Int32,Int32)
Rfc2898DeriveBytes(String,Int32,Int32)
),在这种情况下,您无法复制。
byte[] passBytes = new byte[]
    {164,176,124,62,244,154,226,211,177,90,202,180,12,142,25,225};

byte[] saltBytes = new byte[]
    {173,205,190,172,239,190,242,63,219,205,173,196,218,171,142,214};

var pbkdf2 = new Rfc2898DeriveBytes(passBytes, saltBytes, 1000);
var key = Convert.ToBase64String(pbkdf2.GetBytes(16));