2017-06-30 16 views
2

なぜC#のRfc2898DeriveBytesとgo langのpbkdf2が異なるキーを生成するのですか?C#でRfc2898DeriveBytes、同じく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 ==

何か別のものがありますか?

+0

両方とも同じ反復回数とSHA1を使用していますか? 'passBytes'は有効なUTF-8文字列でないかもしれないので、' passBytes'に 'UTF8'を使用することも疑わしいようです。 – 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バージョンは、パスワードの両方の引数と、Rfc2898DeriveBytes Constructor (Byte[] password, Byte[] salt, Int32 iterations)の両方の引数を[]byte引数とします。

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#の機能*に依存します。 *反復*がC#コンストラクタで指定されていない場合は、デフォルト値は1000になると思いますが、ランダムな塩( 'Rfc2898DeriveBytes(String、Int32、Int32)'と 'Rfc2898DeriveBytes(String、Int32、 Int32) ')、この場合は複製できません。 – putu

関連する問題