英文:
Generate the same keys with Rfc2898DeriveBytes in c# and pbkdf2 in go
问题
为什么C#中的Rfc2898DeriveBytes
和Go语言中的pbkdf2
生成不同的密钥?
你需要注意以下几点:
- 编码方式不同:C#中使用的是UTF-8编码,而Go语言中使用的是原始字节。
- 哈希算法不同:C#中使用的是SHA1算法,而Go语言中使用的也是SHA1算法。
- 迭代次数不同:C#中迭代次数为1000次,而Go语言中迭代次数未指定,默认为1次。
如果你想要生成相同的密钥,可以尝试在Go语言中使用UTF-8编码,并将迭代次数设置为1000次。以下是修改后的Go语言代码:
package main
import (
"encoding/base64"
"golang.org/x/crypto/pbkdf2"
"crypto/sha1"
"fmt"
)
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() []byte {
key := pbkdf2.Key(pass, salt, 1000, 16, sha1.New)
return key
}
func main() {
fmt.Println(base64.StdEncoding.EncodeToString(getKey()))
}
这样修改后的代码应该会生成与C#代码相同的密钥。
英文:
Why do Rfc2898DeriveBytes
in C# and pbkdf2
in go lang generate different keys?
my C# code
<!-- language: 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()));
}
}
output: 77U85CphtSEwPP9a2T/jaQ==
<hr>
golang code
<!-- language: go -->
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()))
}
output: hnuuu+he4aF7vAzA8rfQtw==
Is there something different i must do?
答案1
得分: 1
你在初始化C#实例时使用了不同的变体(使用UTF-8 string
作为参数的构造函数)。此外,正如zaph已经指出的那样,你需要在C#和golang
代码中使用相同的迭代次数。golang
版本接受[]byte
类型的参数作为password和salt,而C#对应的是Rfc2898DeriveBytes Constructor (Byte[] password, Byte[] salt, Int32 iterations)
。
以下是代码示例:
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));
以上代码的输出与golang
版本相同。
英文:
You're using different variant (the constructor that takes UTF-8 string
) when initializing C# instance. In addition, as already pointed by zaph, you need to use same iteration count for both C# and golang
codes. The golang
version takes []byte
arguments both for password and salt, and the C# counterpart is Rfc2898DeriveBytes Constructor (Byte[] password, Byte[] salt, Int32 iterations)
.
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));
The output of above code is the same with golang
version.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论