如何解决SSHA512在C#中为Postfix
我必须使用SSHA512生成密码哈希,该哈希可以与Postfix一起使用。 我有用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=
编码盐+通过v1:
2EXXraKRShKwOOb9TYU4hoXVQPhhujaK2dJVe8/n423tW3dOBBdycUPBluMmRtkNELIocAIkRKR6Rk+R5T43rw==
解决方法
根据Python代码的发布结果
Q5RlBLOCizu/o/iI7NrzqI1lIvMJ5lLngPH1zdeYSdbA+G+wzNcCTwPOwEG/oKM5P3bqrBcm5gLDSdBO3IjnplWHbgqgTBvV
在Base64解码后,以下内容可以导出为salt:
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,b,b1.Length);
Buffer.BlockCopy(b2,b1.Length,b2.Length);
return b;
}
因此,哈希执行如下:
HashAlgorithm algorithm = new SHA512Managed();
byte[] passwordSalt = join(password,salt);
byte[] hash = algorithm.ComputeHash(passwordSalt);
在使用Base64编码之前,必须将哈希值和盐值连接起来
: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);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。