SSHA512 在 C# 中为 Postfix 生成哈希
SSHA512 generating hash in c# for Postfix
我必须使用可以与 Postfix 一起使用的 SSHA512 生成密码哈希。
我有用 Python 编写的哈希生成器,我需要将它重写为 C#。
我用 c# 编写了一些生成哈希的代码,但 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 中生成的散列比 Python 中生成的散列短。
在版本 2 中长度相同。
不幸的是,这两个版本在 Postfix 中都不起作用。无法验证生成的哈希值。
我得到的值:
密码:德州
Python 生成的密码:
Q5RlBLOCizu/o/iI7NrzqI1lIvMJ5lLngPH1zdeYSdbA+G+wzNcCTwPOwEG/oKM5P3bqrBcm5gLDSdBO3IjnplWHbgqgTBvV
C#:
原始盐值 v1:
0xed 0x01 0x97 0x7b 0xc2 0xec 0x29 0x76
编码盐 v1:
7Q+Xe8LsKXY=
编码 salt + 通过 v1 :
2EXXraKRShKwOOb9TYU4hoXVQPhhujaK2dJVe8/n423tW3dOBBdycUPBluMmRtkNELIocAIkRKR6Rk+R5T43rw==
来自 Python 代码的发布结果
Q5RlBLOCizu/o/iI7NrzqI1lIvMJ5lLngPH1zdeYSdbA+G+wzNcCTwPOwEG/oKM5P3bqrBcm5gLDSdBO3IjnplWHbgqgTBvV
经过Base64解码后可以得到如下salt:
55876e0aa04c1bd5 (hex encoded) or VYduCqBMG9U= (Base64 encoded)
在C#代码中,首先salt和password必须进行编码:
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);
我必须使用可以与 Postfix 一起使用的 SSHA512 生成密码哈希。 我有用 Python 编写的哈希生成器,我需要将它重写为 C#。 我用 c# 编写了一些生成哈希的代码,但 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 中生成的散列比 Python 中生成的散列短。 在版本 2 中长度相同。 不幸的是,这两个版本在 Postfix 中都不起作用。无法验证生成的哈希值。
我得到的值:
密码:德州
Python 生成的密码:
Q5RlBLOCizu/o/iI7NrzqI1lIvMJ5lLngPH1zdeYSdbA+G+wzNcCTwPOwEG/oKM5P3bqrBcm5gLDSdBO3IjnplWHbgqgTBvV
C#:
原始盐值 v1:
0xed 0x01 0x97 0x7b 0xc2 0xec 0x29 0x76
编码盐 v1:
7Q+Xe8LsKXY=
编码 salt + 通过 v1 :
2EXXraKRShKwOOb9TYU4hoXVQPhhujaK2dJVe8/n423tW3dOBBdycUPBluMmRtkNELIocAIkRKR6Rk+R5T43rw==
来自 Python 代码的发布结果
Q5RlBLOCizu/o/iI7NrzqI1lIvMJ5lLngPH1zdeYSdbA+G+wzNcCTwPOwEG/oKM5P3bqrBcm5gLDSdBO3IjnplWHbgqgTBvV
经过Base64解码后可以得到如下salt:
55876e0aa04c1bd5 (hex encoded) or VYduCqBMG9U= (Base64 encoded)
在C#代码中,首先salt和password必须进行编码:
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);