2017-03-07 68 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。

我Golang代码看起来是这样,但它不会产生存储数据库相同的字符串。

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

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

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

任何人都可以找到我的错吗?由于

+2

我不知道Golang,但我注意到的第一件事是,他使用'Encoding.Unicode.GetBytes',这意味着它会产生每个字符2个字节的'bytes'和'src'阵列,并随后'dst'数组。你能检查你的Golang代码,它是否正确处理? – Paya

+0

@icza我不明白为什么盐需要被解释为一个十六进制字符串?在数据库中它保存为一个字符串。 –

回答

4

的问题是,C#代码是使用Encoding.Unicode。在围棋应该是:

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天 –