在C#中使用Rfc2898DeriveBytes生成相同的密钥,在Go中使用pbkdf2生成相同的密钥。

huangapple go评论179阅读模式
英文:

Generate the same keys with Rfc2898DeriveBytes in c# and pbkdf2 in go

问题

为什么C#中的Rfc2898DeriveBytes和Go语言中的pbkdf2生成不同的密钥?

你需要注意以下几点:

  1. 编码方式不同:C#中使用的是UTF-8编码,而Go语言中使用的是原始字节。
  2. 哈希算法不同:C#中使用的是SHA1算法,而Go语言中使用的也是SHA1算法。
  3. 迭代次数不同: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	&quot;encoding/base64&quot;
	&quot;golang.org/x/crypto/pbkdf2&quot;
	&quot;crypto/sha1&quot;

)

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类型的参数作为passwordsalt,而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.

huangapple
  • 本文由 发表于 2017年6月30日 21:17:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/44847460.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定