【发布时间】:2016-11-30 13:27:54
【问题描述】:
我有一个简单的类,它有 2 个方法:
private static byte[] PBKDF2(string field, byte[] salt, int iterations, int outputBytes)
{
Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(field, salt);
pbkdf2.IterationCount = iterations;
return pbkdf2.GetBytes(outputBytes);
}
public static string CreateHash(string field, String salt)
{
//if (Array.TrueForAll(salt, x => x == 0))
//{
// RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider();
// csprng.GetBytes(salt);
// string s = Convert.ToBase64String(salt);
//}
byte[] salts = Encoding.ASCII.GetBytes(salt);
byte[] hash = PBKDF2(field, salts, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);
return Convert.ToBase64String(hash);
}
我需要提供一个前端,用户可以在其中输入一个简单的字符串,例如“abc”,并且我需要根据它生成一个盐。这就是我要存储在数据库中并使用它传递给上述方法(CreateHash)去识别 数据。这个盐/密钥需要能够解密回来,我必须在前端显示。
我也可以使用其他类/库。它不必是 Rfc2898DeriveBytes。
请提供一些关于如何实现此盐/密钥生成功能的意见。这个盐不能是随机值。
谢谢!
【问题讨论】:
-
盐应该是随机的,而不是基于用户输入。盐的全部意义在于,如果有人两次输入相同的输入,则会得到两个不同的输出。如果您这样做是因为您在验证
byte[]时需要“了解盐”,那么您只需在二进制 blob 的前面或后面添加或附加盐,当您去验证时你拔掉盐并将其输入到 PBKDF2 函数中。 -
可能solution 但它正在使用 Rfc2898... 你为什么不想使用它?
-
@ScottChamberlain 我知道盐应该是动态的,但这里的要求不同。这不适用于密码存储。我们需要对数据进行去标识化并将它们存储在文件中。每次文件附带一些数据时,我们都会加密并生成另一个文件。所有个人信息均已取消识别。但是例如对于一个给定的字段,比如名字 David,它总是需要转换为与之前生成的相同的加密字符串。不是我定义的!如果我修复盐并传递给 Rfc2898DeriveBytes 以获得相同输入的相同字符串。
-
那为什么要使用
Rfc2898DeriveBytes而不仅仅是一个简单的哈希? -
@ScottChamberlain 简单散列不够安全,而且最终散列必须是单向散列……在我们的例子中,盐可以解密,但最终加密字符串是单向加密。
标签: c# encryption cryptography salt