当前位置: 首页 > 知识库问答 >
问题:

如何在我的salt中将SHA-512与Rfc2898DeriveBytes一起使用

柯正谊
2023-03-14

我对密码学是个新手,但是学习。我从网上的研究中收集了许多不同的建议,并制作了自己的类,用于处理哈希、salt、键拉伸以及关联数据的比较/转换。

在研究了内置的。NET密码学库,我发现我拥有的仍然只有SHA-1。但我得出的结论是,这并不坏,因为我使用了哈希过程的多次迭代。对吗?

但如果我想从更健壮的SHA-512开始,我如何在下面的代码中实现它呢?提前谢谢。

using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;

public class CryptoSaltAndHash
{
    private string strHash;
    private string strSalt;
    public const int SaltSizeInBytes = 128;
    public const int HashSizeInBytes = 1024;
    public const int Iterations = 3000;

    public string Hash { get { return strHash; } }
    public string Salt { get { return strSalt; } }

    public CryptoSaltAndHash(SecureString ThisPassword)
    {
        byte[] bytesSalt = new byte[SaltSizeInBytes];
        using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider())
        {
            crypto.GetBytes(bytesSalt);
        }
        strSalt = Convert.ToBase64String(bytesSalt);
        strHash = ComputeHash(strSalt, ThisPassword);
    }

    public static string ComputeHash(string ThisSalt, SecureString ThisPassword)
    {
        byte[] bytesSalt = Convert.FromBase64String(ThisSalt);
        Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(
            convertSecureStringToString(ThisPassword), bytesSalt, Iterations);
        using (pbkdf2)
        {
            return Convert.ToBase64String(pbkdf2.GetBytes(HashSizeInBytes));
        }
    }

    public static bool Verify(string ThisSalt, string ThisHash, SecureString ThisPassword)
    {
        if (slowEquals(getBytes(ThisHash), getBytes(ComputeHash(ThisSalt, ThisPassword))))
        {
            return true;
        }
        return false;
    }

    private static string convertSecureStringToString(SecureString MySecureString)
    {
        IntPtr ptr = IntPtr.Zero;
        try
        {
            ptr = Marshal.SecureStringToGlobalAllocUnicode(MySecureString);
            return Marshal.PtrToStringUni(ptr);
        }
        finally
        {
            Marshal.ZeroFreeGlobalAllocUnicode(ptr);
        }
    }

    private static bool slowEquals(byte[] A, byte[] B)
    {
        int intDiff = A.Length ^ B.Length;
        for (int i = 0; i < A.Length && i < B.Length; i++)
        {
            intDiff |= A[i] ^ B[i];
        }
        return intDiff == 0;
    }

    private static byte[] getBytes(string MyString)
    {
        byte[] b = new byte[MyString.Length * sizeof(char)];
        System.Buffer.BlockCopy(MyString.ToCharArray(), 0, b, 0, b.Length);
        return b;
    }
}

注意:我已经参考了很多来自https://crackstation.net/hashing-security.htm.slowEquals比较方法是通过防止分支来规范执行时间。SecureString的用途是在这个类和我的web应用程序中的其他类和页面之间有一个加密形式的密码传递。虽然这个网站将通过HTTPS,但在合理的范围内,尽可能多地确保事情尽可能安全总是很好的。

在我的代码中,我将密钥字符串设置为128字节(尽管有时会变大,这很好),哈希大小设置为1KB,迭代次数设置为3000。它比典型的64字节salt、512字节hash和1000或2000次迭代稍微大一点,但登录速度和应用程序性能的优先级非常低。

想法?

共有3个答案

丘向荣
2023-03-14

回答问题:从“SecurityDriven.NET”一书中下载免费代码示例。查找接受HMAC工厂的PBKDF2类。HMACSHA512工厂可供选择。

既然你是密码学的新手,我也强烈建议你读这本书(例如。为了充分理解CodesInChaos提出的观点)。

穆锋
2023-03-14

如果任何人通过搜索遇到这个问题,现在Microsoft提供Microsoft。AspNetCore。密码学。KeyDerivation NuGet包,允许将PBKDF2与SHA-256和SHA-512哈希函数一起使用。文档可从docs获得。微软通用域名格式。

汤飞
2023-03-14

>

  • 3000次迭代是相当低的。就算10000也是低的。但是您需要权衡额外迭代的安全增益和攻击者通过尝试经常登录来攻击您的服务器的风险,这会触发每次尝试的昂贵哈希。
  • 在大于128位/16字节的盐中没有点。盐应该是独一无二的,仅此而已。
  • 散列大小大于本机大小(SHA-1为20字节)会降低防御者的性能,但不会降低攻击者的性能。因为这意味着您可以负担更少的迭代,它实际上削弱了安全性。

    例如,以与3000次迭代的1024字节哈希相同的成本,您可以负担156000次迭代的20字节哈希,这是破解成本的52倍。

    要使用SHA-2,您需要一个完全不同的PBKDF2实现,即随附的实现。net硬编码为使用SHA-1。

    如果您费心使用第三方库,我宁愿使用bcrypt库,因为它对基于GPU的攻击者具有更强的抵御能力。

    您的API很难使用,因为您将salt管理推送到调用方,而不是在Create/Verify函数中处理它。

    使用SecureString然后将其转换为String是愚蠢的。这抵消了首先使用SecureString的全部意义。

    就我个人而言,我不会在典型的应用程序中使用SecureString。只有将它与广泛的全堆栈安全检查相结合,检查密码是否从未存储在String中,并且一旦不再需要密码,就总是从可变存储中删除,这才是值得的。

    我不会在实例html" target="_blank">变量中存储密码/密码。只需将它们保留在相关功能的本地。我只将配置存储在实例变量中(例如迭代计数)。

    虽然SHA-1在加密方面被削弱,但攻击会产生冲突。因为密码散列冲突是不相关的,所以您关心的是第一个图像前攻击。SHA-1在这方面仍然相当强大。

    SHA-512的主要优势不是它的密码学更强(尽管它是),而是64位算术花费攻击者比防御者更多,因为防御者可能会使用64位英特尔处理器,它提供快速的64位算术。

  •  类似资料:
    • 作为练习,我用C编写了自己的SHA-512哈希函数实现。我知道它是有效的,因为我从abc 在Base64中。就像在测试现场一样。 我有两个问题: > 如何加密我的密码?如果我有: 我应该创建字符串以输入盐通过="ssssssssmy密钥密码"吗?或者可能以相反的方式?我试图在谷歌上到处寻找答案——我找不到真正合适的东西。 在base64中,我应该使用什么编码来获得像/etc/shadow文件中那样

    • 我想找到一个解决方案或方法,使我能够添加盐和控制迭代次数。本机Rfc2898DeriveBytes基于HMACSHA1。理想情况下,使用SHA-256或SHA-512将使系统经得起未来的考验。 这是迄今为止我发现的最好的例子:http://jmedved.com/2012/04/pbkdf2-with-sha-256-and-others/但是当我用SHA-256运行它时,它实际上比用SHA-51

    • 我正在研究一个已经用MD5(没有salt)散列用户密码的系统。我想使用SHA-512和SALT更安全地存储密码。 虽然这对于将来的密码来说很容易实现,但我也想修改现有的MD5散列密码,最好不强迫所有用户更改他们的密码。我的想法是只使用SHA-512和一个适当的salt来散列现有的MD5散列。然后,我可以在数据库中设置一些标志,指示哪些密码是从纯文本散列出来的,哪些密码是从MD5散列出来的。或者我可

    • 问题内容: 如何将chmod与Node.js一起使用? 程序包中有一个方法应该执行此操作,但是我不知道第二个参数是什么。 fs.chmod(路径,模式,[回调]) 异步chmod(2)。除了可能的异常外,没有其他参数被赋予完成回调。 fs.chmodSync(路径,模式) 同步chmod(2)。 (来自Node.js文档) 如果我做类似的事情 没有任何反应(文件未更改为该模式)。 也不起作用。 我

    • 问题内容: 我一直在研究一些有关Java字符串加密技术的信息,但不幸的是,我还没有找到如何在Java中使用SHA-512对String进行哈希处理的很好的教程。我读了一些有关MD5和Base64的博客,但是它们并不像我想要的那样安全(实际上,Base64不是一种加密技术),所以我更喜欢SHA-512。 问题答案: 您可以将其用于SHA-512

    • 我想向我的kafka集群添加新用户,方法似乎是在zookeeper数据库中添加SCRAM-SHA-512/256配置,但我只知道如何使用命令行实用程序来完成,如下所示: 有没有使用Kafka API for Java的替代方法?