将byte[]复制到另一个byte[]中出现问题

3

我有一种方法可以创建哈希密码。但是在salt.CopyTo(pwd, 0)处崩溃了。提示目标byte[]太小了。我该怎么解决这个问题?

public static byte[] CreateHashedPassword(string password, byte[] salt)
        {
            SHA1 sha1 = SHA1.Create();
            byte[] pwd = CustomHelpers.StringToByteArray(password);
            salt.CopyTo(pwd, 0);
            sha1.ComputeHash(pwd);

            return pwd;            
        }

3
你真的想要覆盖从密码的SHA生成的字节的一部分并将其替换为盐值,还是想在这些字节之前插入盐值? - Lasse V. Karlsen
我的意图是在将密码哈希在一起之前,将盐添加到密码的开头。 - Jova
3个回答

9

您需要创建一个更长的字节数组,以包含盐和密码:

    byte[] result = new byte[salt.Length + password.Length];
    salt.CopyTo(result, 0);
    password.CopyTo(result, salt.Length);

它不应该是随机的,你需要知道它是什么才能测试密码是否与哈希和加盐的密码匹配。 - Zach Johnson
1
Zach:它应该是随机的,但你应该保留一份副本。但我已经改变了我的答案,因为我意识到他试图在数组的开头插入字节。 - Mark Byers
据我所知,它不需要是随机的,因为盐的目的是为了防止彩虹表攻击。即使坏人知道盐是什么,他们仍然必须手动计算密码的哈希值。 - Zach Johnson
1
如果你在每个密码中使用相同的盐值,那么你仍然无法阻止字典攻击。盐值的作用是让攻击者只能一次尝试一个密码来暴力破解你的密码数据库,而不是一次性全部尝试。 - Anon.
非常好用,Mark。非常感谢你。 是的,我的盐值对于每个密码都是随机的。这是最安全的做法。 - Jova

1

可能是这样的吗?

public static byte[] CreateHashedPassword(string password, byte[] salt) 
{ 
    SHA1 sha1 = SHA1.Create(); 
    byte[] pwd = CustomHelpers.StringToByteArray(password);
    byte[] pwdPlusSalt = new byte[salt.Length + pwd.Length];
    salt.CopyTo(pwdPlusSalt, 0); 
    pwd.CopyTo(pwdPlusSalt, salt.Length); 

    return sha1.ComputeHash(pwdPlusSalt);
}

谢谢Jeffrey,这正是我在添加Mark建议后代码的样子。 - Jova

0

盐有多大?你打算添加到密码中吗?

以下是如何将其添加到密码开头的方法:

byte[] pwdAndSalt = new byte[pwd.Length + salt.Length];
for (int i = 0; i < pwdAndSalt.Length; i++)
{
    if (i < salt.Length)
    {
        pwdAndSalt[i] = salt[i];
    }
    else
    {
        pwdAndSalt[i] = pwd[i - salt.Length];
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接