我需要更新一些在.Net中使用PBKDF2实现的代码,Rfc2898DeriveBytes
来散列用户凭据。
据我所知,这个功能使用SHA-1。我需要更新系统密码散列的底层散列算法以使用SHA-256(这是客户端IT-SEC要求)。
完成一些阅读之后,似乎最好继续使用Key派生函数,但是PBKDF2不允许您指定应该使用的算法,这对我来说显然是一个问题。
我们的系统使用的是.NET 4.5.1,目前不是升级的选项,我有理由相信它不是一个可以引用任何新的.NET核心的选项。我听说过包含一个新的实现PBKDF2允许您指定算法。
我想不惜一切代价避免自制的实施,因为这是Crypto-Club的第一条规则吗?
任何关于什么是最佳实践的指导将不胜感激。
由于
答案 0 :(得分:1)
答案 1 :(得分:1)
假设您使用的是Win7 +,则可以P / Invoke到BCryptDeriveKeyPBKDF2。
private static void PBKDF2(
string password,
byte[] salt,
int iterationCount,
string hashName,
byte[] output)
{
int status = SafeNativeMethods.BCryptOpenAlgorithmProvider(
out SafeNativeMethods.SafeBCryptAlgorithmHandle hPrf,
hashName,
null,
SafeNativeMethods.BCRYPT_ALG_HANDLE_HMAC_FLAG);
using (hPrf)
{
if (status != 0)
{
throw new CryptographicException(status);
}
byte[] passBytes = Encoding.UTF8.GetBytes(password);
status = SafeNativeMethods.BCryptDeriveKeyPBKDF2(
hPrf,
passBytes,
passBytes.Length,
salt,
salt.Length,
iterationCount,
output,
output.Length,
0);
if (status != 0)
{
throw new CryptographicException(status);
}
}
}
[SuppressUnmanagedCodeSecurity]
private static class SafeNativeMethods
{
private const string BCrypt = "bcrypt.dll";
internal const int BCRYPT_ALG_HANDLE_HMAC_FLAG = 0x00000008;
[DllImport(BCrypt, CharSet = CharSet.Unicode)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern int BCryptDeriveKeyPBKDF2(
SafeBCryptAlgorithmHandle hPrf,
byte[] pbPassword,
int cbPassword,
byte[] pbSalt,
int cbSalt,
long cIterations,
byte[] derivedKey,
int cbDerivedKey,
int dwFlags);
[DllImport(BCrypt)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
private static extern int BCryptCloseAlgorithmProvider(IntPtr hAlgorithm, int flags);
[DllImport(BCrypt, CharSet = CharSet.Unicode)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern int BCryptOpenAlgorithmProvider(
out SafeBCryptAlgorithmHandle phAlgorithm,
string pszAlgId,
string pszImplementation,
int dwFlags);
internal sealed class SafeBCryptAlgorithmHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public SafeBCryptAlgorithmHandle() : base(true)
{
}
protected override bool ReleaseHandle()
{
return BCryptCloseAlgorithmProvider(handle, 0) == 0;
}
}
}
答案 2 :(得分:0)
我会告诉你我会做什么:我会采用最新的来源(不完全是最新的,因为它使用Span<>
......只是有点旧:-)){{来自corefx github
您需要完整的代码:
加上
中的两种方法(Rfc2898DeriveBytes
和GenerateRandom
)
然后,您有一些WriteInt
的来电,您必须替换某些消息,例如SR.*something*
,以及您需要替换的"some error"
SR.Format
。
然后您将拥有(几乎)最新版本的string.Format
,其中有一个构造函数可以作为参数Rfc2898DeriveBytes
接受。
这应该是最终结果:https://ideone.com/lb2Qya
我错误地将源代码放在命名空间HashAlgorithmName.SHA256
中......糟糕的坏主意......我必须在My.System
前加上所有命名空间: - (