随机字符串 | 密码盐建议

3

如果我们将我下面的方法与RCIX在这个答案中提出的方法进行比较,哪一个更有效率,为什么?

private string RandomString(int length = 25)
{
    const string chars = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789#@%&";
    StringBuilder sbSalt = new StringBuilder();

    for (int i = 0; i < length; i++)
    {
        int inx = 0;

        inx = rnd.Next(0, chars.Length);
        sbSalt.Append(chars[inx]);
    }

    return sbSalt.ToString();
}

private Random rnd = new Random();

我之所以使用"aAbBcC..."而不是"abc...ABC...",是为了增加每个字母的大小写之间随机化的概率,因为它们相邻。
此外,对于密码盐,最好保留重复字符还是确保每个字符在盐中只出现一次?然而,如果允许重复字符,则可以生成更多的盐组合。
提前致谢!
更新#1:
我意识到如果再次调用RandomString函数,它将返回完全相同的随机字符串,所以为了解决这个问题,我通过将rnd声明为新的Random仅一次并将其移动到函数外部来进行修复。

关于您的更新:Random在其构造函数中使用种子。当提供相同的种子时,.Next()函数返回相同的数字集合。如果未将种子插入到Random构造函数中,则它将使用基于DateTime.Now的值。 - Stefan
那是另一个有用的要记住的事情。 我使用的解决方法好吗? - Hello World
@Stefan:我不同意在函数内创建Random对象。这将始终基于当前时间创建一个新实例。如果您多次实例化该类,则有可能创建相同的种子。最好为特定目的创建一个Random对象,并在整个应用程序的生命周期中使用它以确保正确的分布(当然,在重复周期内)。 - Caramiriel
@Caramiriel:你说得对,缺省种子是基于一个32位数字(滴答数)的。获得相同种子的机会可能比命中算法的非随机性更大。 - Stefan
我终于明白了Random如何获得其“随机”值,这确实是一种相当聪明和好的方法。谢谢你,Stefan。该函数目前位于静态类中,并且应在服务器上运行。这意味着只有在运行时才会创建一个名为Random的新实例rnd,并将使用相同的rnd实例数天,根据Stefan的说法这是一个不好的主意,我也同意。我有两个解决方案。 - Hello World
显示剩余3条评论
2个回答

1
盐的主要用途是使字典攻击更加困难。我喜欢在密钥本身上创建脏数据,到目前为止,它非常高效,因为我可以每秒运行数百个加密/解密通过WCF服务:
// sKey being the encryption key

// adding dirt to the string to make it harder to guess using a dictionary attack.
byte[] Dirt = Encoding.ASCII.GetBytes(sKey.Length.ToString());

// The Key will be generated from the specified Key and dirt.
PasswordDeriveBytes FinalKey = new PasswordDeriveBytes(sKey, Dirt);

// to use : FinalKey.GetBytes(16)

啊,我明白了。不过我更希望这个“dirt”是更加可变的东西。但这只是我的看法。感谢您的回答!我相信这个知识在未来某个时候会派上用场。 - Hello World

1

我选择使用"aAbBcC..."而不是"abc...ABC..."的原因是为了增加每个字母小写和大写之间随机化的概率,因为它们相邻。但这不会增加大写和小写之间的随机性。

您可以通过掷骰子来测试,数字的位置不会改变奇数和偶数的概率。

效率将取决于您如何定义。您想让代码更易读还是更难读?您需要高性能吗?可维护性?

通常情况下,我不倾向于以上任何一种。

保留重复字符还是确保每个字符在盐中只遇到一次哪种更好?

实际上,如果允许重复字符,则排列组合的数量会增加。

这意味着字符串将更难被暴力破解。

如果您要将此salt用于加密技术,则最好使用框架的库,例如GetBytes()

http://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.aspx


我认为它会增加随机性的原因是,我不太相信 Random 库的随机性足够好。我也不太理解它的工作原理,这让我感到困扰。在学校里,我们被教导说,如果你的代码容易被其他程序员阅读,那么它就是一段好的代码。你有什么看法?我更希望在安全、快速和资源使用较少之间取得平衡。在混合和/或加密字符串进行哈希和/或加密之前,所有内容都会转换为字节数组。这是库要求我做的事情。 - Hello World
随机性非常好(这是轻描淡写的说法)。易读的代码通常是好代码的最佳标准(前提是它也是逻辑上正确的)。尽管在超高性能环境中,微调代码可能会更好,比如重用对象,避免循环等。很有可能你的代码开销与加密算法相比是极小的。因此,除非你要运行代码数千次,否则它已经足够好了。所以这取决于你 :) …希望这可以帮到你。 - Stefan

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