簡體   English   中英

SSHA512 在 c# 中為 Postfix 生成 hash

[英]SSHA512 generating hash in c# for Postfix

我必須使用可以與 Postfix 一起使用的 SSHA512 生成密碼 hash。 我有用 Python 編寫的 hash 生成器,我需要將其重寫為 C#。 我在 c# 中編寫了一些生成 hash 的代碼,但 Postfix 無法驗證生成的密碼。

Python代碼:

def generate_ssha512_password(p):
"""Generate salted SHA512 password with prefix '{SSHA512}'.
Return SSHA instead if python is older than 2.5 (not supported in module hashlib)."""
p = str(p).strip()
try:
    from hashlib import sha512
    salt = os.urandom(8)
    pw = sha512(p)
    pw.update(salt)
    return '{SSHA512}' + b64encode(pw.digest() + salt)

還有我的 C# 代碼版本 1:

        public static string CreateSalt(int size)
    {
        //Generate a cryptographic random number.
        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
        byte[] buff = new byte[size];
        rng.GetBytes(buff);
        return Convert.ToBase64String(buff);
    }
        public static string GenerateHash(string input, string salt)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(input + salt);
        SHA512 sHA512ManagedString = new SHA512Managed();
        byte[] hash = sHA512ManagedString.ComputeHash(bytes);
        return Convert.ToBase64String(hash);
    }

C#代碼版本2:

        public static byte[] CreateSaltRaw(int size)
    {
        //Generate a cryptographic random number.
        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
        byte[] buff = new byte[size];
        rng.GetBytes(buff);
        return buff;
    }
    public static string GenerateHash2(string input, byte[] salt)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(input + Convert.ToBase64String(salt));
        SHA512 sHA512ManagedString = new SHA512Managed();
        byte[] hash = sHA512ManagedString.ComputeHash(bytes);
        List<byte> pass = hash.ToList();
        foreach (var s in salt)
        {
            pass.Add(s);
        }
        //return Convert.ToBase64String(hash);
        return Convert.ToBase64String(pass.ToArray());
    }

在版本 1 中生成的 hash 比在 Python 中生成的 hash 短。 在版本 2 中,長度相同。 不幸的是,這兩個版本都不能在 Postfix 中工作。 生成的 hash 無法驗證。

我得到的價值觀:

密碼:德州

Python 生成密碼:

Q5RlBLOCizu/o/iI7NrzqI1lIvMJ5lLngPH1zdeYSdbA+G+wzNcCTwPOwEG/oKM5P3bqrBcm5gLDSdBO3IjnplWHbgqgTBvV

C#:

原鹽值 v1:

0xed 0x01 0x97 0x7b 0xc2 0xec 0x29 0x76

編碼鹽v1:

7Q+Xe8LsKXY=

編碼鹽+通過v1:

2EXXraKRShKwOOb9TYU4hoXVQPhhujaK2dJVe8/n423tW3dOBBdycUPBluMmRtkNELIocAIkRKR6Rk+R5T43rw==

從 Python 代碼的發布結果

Q5RlBLOCizu/o/iI7NrzqI1lIvMJ5lLngPH1zdeYSdbA+G+wzNcCTwPOwEG/oKM5P3bqrBcm5gLDSdBO3IjnplWHbgqgTBvV

Base64 解碼后可以得到以下鹽:

55876e0aa04c1bd5 (hex encoded) or VYduCqBMG9U= (Base64 encoded) 

在 C# 代碼中,必須先對鹽和密碼進行編碼:

byte[] salt = Convert.FromBase64String("VYduCqBMG9U="); 
byte[] password = Encoding.ASCII.GetBytes("texas"); // Here the encoding of the Python code must be used

在散列之前,必須連接兩個byte[] 由於稍后需要再次連接byte[] ,因此實現輔助方法很有用:

private static byte[] join(byte[] b1, byte[] b2)
{
    byte[] b = new byte[b1.Length + b2.Length];
    Buffer.BlockCopy(b1, 0, b, 0, b1.Length);
    Buffer.BlockCopy(b2, 0, b, b1.Length, b2.Length);
    return b;
}

因此,哈希執行如下:

HashAlgorithm algorithm = new SHA512Managed();
byte[] passwordSalt = join(password, salt);
byte[] hash = algorithm.ComputeHash(passwordSalt);

在 Base64 編碼之前,hash 和 salt 必須連接:

byte[] hashSalt = join(hash, salt);
string hashSaltB64 = Convert.ToBase64String(hashSalt); // Q5RlBLOCizu/o/iI7NrzqI1lIvMJ5lLngPH1zdeYSdbA+G+wzNcCTwPOwEG/oKM5P3bqrBcm5gLDSdBO3IjnplWHbgqgTBvV

要處理隨機鹽,您可以使用例如您的CreateSaltRaw方法並簡單地替換

byte[] salt = Convert.FromBase64String("VYduCqBMG9U=");  

經過

byte[] salt = CreateSaltRaw(8);         

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM