2017-03-07 20 views
2

古いC#コードをGolangに変換する必要があります。 C#のコードは、この `C#SHA1コードをGolangに変換する

byte[] bytes = Encoding.Unicode.GetBytes(password); 
byte[] src = Encoding.Unicode.GetBytes(salt); 
byte[] dst = new byte[src.Length + bytes.Length]; 
Buffer.BlockCopy(src, 0, dst, 0, src.Length); 
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); 
HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); 
byte[] inArray = algorithm.ComputeHash(dst); 
return Convert.ToBase64String(inArray); 

のように見えるので、私はラインでのコード行を検査し、私は彼が塩とパスワードをバイト配列に変換使用理解し、その後、彼は「DST」配列にこれらの配列をコピーしました。その後、SHA1アルゴリズムを使用して、この配列をbase64stringに変換します。

My Golangコードはこのように見えますが、データベースに保存されているのと同じ文字列は作成されません。

s := "fish123" 
salt := "227EA7ABD26E40608A6EDEB209058D93A632D1D1A52246D0A27F6E447B16AEBF" 

h1 := sha1.New() 
h1.Write([]byte(salt)) 
h1.Write([]byte(s)) 

hashedPassword := base64.StdEncoding.EncodeToString(h1.Sum(nil)) 

誰かが私の誤りを見つけることができますか?ありがとう

+2

私はゴランを知らないけど、最初に気付いたのは彼が 'Encoding.Unicode.GetBytes'を使っていることです。つまり' bytes'と 'src'配列の文字あたり2バイトを生成し、 'dst'配列。これを正しく処理しているGolangコードを確認できますか? – Paya

+0

@iczaなぜ塩が16進文字列として解釈される必要があるのか​​分かりませんか?データベースでは、文字列として保存されました。 –

答えて

4

問題は、C#コードがEncoding.Unicodeを使用していることです。 Goでは、次のようになります。

package main 

import (
    "crypto/sha1" 
    "encoding/base64" 
    "encoding/binary" 
    "fmt" 
    "unicode/utf16" 
) 

func main() { 
    s := "fish123" 
    salt := "227EA7ABD26E40608A6EDEB209058D93A632D1D1A52246D0A27F6E447B16AEBF" 

    h1 := sha1.New() 
    h1.Write(convertUTF16ToLittleEndianBytes(salt)) 
    h1.Write(convertUTF16ToLittleEndianBytes(s)) 

    b64 := base64.StdEncoding.EncodeToString(h1.Sum(nil)) 
    fmt.Println(b64) 
} 

func convertUTF16ToLittleEndianBytes(s string) []byte { 
    u := utf16.Encode([]rune(s)) 
    b := make([]byte, 2*len(u)) 
    for index, value := range u { 
     binary.LittleEndian.PutUint16(b[index*2:], value) 
    } 
    return b 
} 

convertUTF16ToLittleEndianBytesはSOの別の応答から取得されました。

+0

は魅力的な作品です!ありがとう、私は2日間これを苦労してきた男 –

関連する問題