【发布时间】:2017-12-04 11:20:54
【问题描述】:
为什么 C# 中的 Rfc2898DeriveBytes 和 go lang 中的 pbkdf2 生成不同的密钥?
我的C#代码
using System;
using System.Security.Cryptography;
using System.Text;
public class Test
{
private static byte[] passBytes = new byte[]
{164,176,124,62,244,154,226,211,177,90,202,180,12,142,25,225};
private static byte[] saltBytes = new byte[]
{173,205,190,172,239,190,242,63,219,205,173,196,218,171,142,214};
public static byte[] GetKey()
{
var key = new Rfc2898DeriveBytes(Encoding.UTF8.GetString(passBytes, 0, 16), saltBytes).GetBytes(16);
return key;
}
public static void Main()
{
System.Console.WriteLine(Convert.ToBase64String(GetKey()));
}
}
输出: 77U85CphtSEwPP9a2T/jaQ==
golang 代码
package main
import (
b64 "encoding/base64"
"golang.org/x/crypto/pbkdf2"
"crypto/sha1"
)
var (
pass[]byte = []byte{164,176,124,62,244,154,226,211,177,90,202,180,12,142,25,225}
salt[]byte = []byte{173,205,190,172,239,190,242,63,219,205,173,196,218,171,142,214}
)
func getKey() (key[]byte){
key = pbkdf2.Key(pass,salt,1000,16,sha1.New)
return
}
func main() {
print(b64.StdEncoding.EncodeToString(getKey()))
}
输出: hnuuu+he4aF7vAzA8rfQtw==
我必须做些不同的事情吗?
【问题讨论】:
-
它们是否都使用相同的迭代次数和 SHA1?同样在
passBytes上使用UTF8似乎很可疑,因为passBytes可能不是有效的UTF-8 字符串。 -
接收字符串的 Rfc2898DeriveBytes ctor 立即通过 UTF-8 编码将其转换为字节。您可以通过将字节直接传递给基于 byte[] 的 ctor 来跳过字符串的创建。
-
@bartonjs c# 代码有什么问题?
Encoding.UTF8.GetString(passBytes, 0, 16)不是应该在passBytes上使用的正确编码吗? -
@avut 我的意思是,您有字节,您可以将其转换为字符串(通过 UTF8),然后将其传递给将字符串转换为字节(通过 UTF8)的构造函数。您只需使用直接获取字节的构造函数之一即可节省工作。
-
@bartonjs 好的!我明白你的意思。但是为什么输出不同不应该相同呢?是什么使输出不同。 C# 中的默认编码不是 UTF-16 吗?那么将字符串转换为 UTF-8 应该给出相同的输出吗?我很困惑。