2017-06-30 69 views
2

爲什麼Rfc2898DeriveBytes在C#中和pbkdf2中go lang生成不同的密鑰?在c#和pbkdf2中使用Rfc2898DeriveBytes生成相同的密鑰

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 ==

有什麼不同,我必須做的?

+0

它們是否都使用相同的迭代計數和SHA1?在'passBytes'上使用'UTF8'似乎是可疑的,因爲'passBytes'可能不是一個有效的UTF-8字符串。 – zaph

+0

只接受一個字符串的Rfc2898DeriveBytes ctors立即通過UTF-8編碼將其轉換爲字節。您只需將字節直接傳遞給基於byte []的ctor即可跳過創建字符串。 – bartonjs

+0

@bartonjs在C#代碼什麼是錯的?是'Encoding.UTF8.GetString(passBytes,0,16)'不是正確的編碼應該用在'passBytes'上嗎? – avut

回答

1

在初始化C#實例時,您正在使用不同的變體(構造函數採用UTF-8 string)。另外,正如zaph已經指出的那樣,您需要對C#和golang代碼使用相同的迭代計數。 golang版本的[]byte參數均爲密碼,而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版本相同。

+0

感謝您的回覆。如果我需要複製golang中的C#代碼? – avut

+0

@avut它取決於您想要複製哪個* C#功能*。如果* iterations *沒有在C#構造函數中指定,我認爲默認值是1000.但是,有一些C#構造函數使用隨機salt('Rfc2898DeriveBytes(String,Int32,Int32)'和'Rfc2898DeriveBytes(String,Int32, Int32)'),在這種情況下,你不能複製。 – putu

相關問題