首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SSHA512在c#中为后缀生成散列

SSHA512在c#中为后缀生成散列
EN

Stack Overflow用户
提问于 2020-08-11 06:03:46
回答 1查看 368关注 0票数 2

我必须用SSHA512生成密码哈希,它可以与后缀一起工作。我有用Python编写的散列生成器,我需要将它重写到C#。我用c#编写了一些生成散列的代码,但是后缀无法验证生成的密码。

Python代码:

代码语言:javascript
复制
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:

代码语言:javascript
复制
        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:

代码语言:javascript
复制
        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中,长度是相同的。不幸的是,这两个版本在后缀中都不起作用。无法验证生成的哈希。

我得到的价值:

密码:德州

Python生成的密码:

代码语言:javascript
复制
Q5RlBLOCizu/o/iI7NrzqI1lIvMJ5lLngPH1zdeYSdbA+G+wzNcCTwPOwEG/oKM5P3bqrBcm5gLDSdBO3IjnplWHbgqgTBvV

C#:

原盐值v1:

代码语言:javascript
复制
0xed 0x01 0x97 0x7b 0xc2 0xec 0x29 0x76

编码盐v1:

代码语言:javascript
复制
7Q+Xe8LsKXY=

编码salt + pass v1:

代码语言:javascript
复制
2EXXraKRShKwOOb9TYU4hoXVQPhhujaK2dJVe8/n423tW3dOBBdycUPBluMmRtkNELIocAIkRKR6Rk+R5T43rw==
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-11 10:23:03

来自Python代码的发布结果

代码语言:javascript
复制
Q5RlBLOCizu/o/iI7NrzqI1lIvMJ5lLngPH1zdeYSdbA+G+wzNcCTwPOwEG/oKM5P3bqrBcm5gLDSdBO3IjnplWHbgqgTBvV

在Base64解码之后,可以以salt的形式导出以下内容:

代码语言:javascript
复制
55876e0aa04c1bd5 (hex encoded) or VYduCqBMG9U= (Base64 encoded) 

在C#代码中,必须首先对salt和密码进行编码:

代码语言:javascript
复制
byte[] salt = Convert.FromBase64String("VYduCqBMG9U="); 
byte[] password = Encoding.ASCII.GetBytes("texas"); // Here the encoding of the Python code must be used

在散列之前,必须将两个byte[]连接起来。由于稍后需要再次连接byte[],所以实现助手方法很有用:

代码语言:javascript
复制
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;
}

因此,哈希按如下方式执行:

代码语言:javascript
复制
HashAlgorithm algorithm = new SHA512Managed();
byte[] passwordSalt = join(password, salt);
byte[] hash = algorithm.ComputeHash(passwordSalt);

在Base64编码之前,必须连接散列和salt:

代码语言:javascript
复制
byte[] hashSalt = join(hash, salt);
string hashSaltB64 = Convert.ToBase64String(hashSalt); // Q5RlBLOCizu/o/iI7NrzqI1lIvMJ5lLngPH1zdeYSdbA+G+wzNcCTwPOwEG/oKM5P3bqrBcm5gLDSdBO3IjnplWHbgqgTBvV

要处理随机盐,可以使用例如CreateSaltRaw方法,只需替换

代码语言:javascript
复制
byte[] salt = Convert.FromBase64String("VYduCqBMG9U=");  

通过

代码语言:javascript
复制
byte[] salt = CreateSaltRaw(8);         
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63352358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档