gpt4 book ai didi

c# - 使用 SQL Server 2008 CLR 进行密码哈希处理

转载 作者:行者123 更新时间:2023-11-30 17:02:30 26 4
gpt4 key购买 nike

我正在尝试实现一种解决方案,使用 SHA-512 算法在 SQL Server 2008 中对密码进行散列和加盐处理。此解决方案基于 Michael Coles 的书“Expert SQL Server 2008 Encryption”。根据他的示例,我能够在 visual studio 2010(C# 中的 .NET 3.5)中构建项目并部署到 SQL Server 2008(如下面的代码所示)。

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Security.Cryptography;

namespace Apress.Samples
{
public partial class CustomEncryption
{
[Microsoft.SqlServer.Server.SqlFunction
(
IsDeterministic = true,
DataAccess = DataAccessKind.None
)]
public static SqlBytes SaltedHash
(
SqlString Algorithm,
[SqlFacet(MaxSize = -1)] SqlBytes PlainText,
SqlBytes Salt
)
{
// Return NULL if any of the parameters is NULL
if (Algorithm.IsNull || PlainText.IsNull || Salt.IsNull)
return SqlBytes.Null;

// Determine which algorithm to use
bool HashDefined = true;
HashAlgorithm Hash = null;
switch (Algorithm.Value.ToUpper())
{
case "SHA256":
Hash = new SHA256Managed();
break;

case "SHA384":
Hash = new SHA384Managed();
break;

case "SHA512":
Hash = new SHA512Managed();
break;

default:
HashDefined = false;
break;
}
if (!HashDefined)
throw new Exception
("Unsupported hash algorithm - use SHA256, SHA384 or SHA512");

// Combine the plaintext with the salt
byte[] PlainTextWithSalt = new byte[PlainText.Length + Salt.Length];
for (long i = 0; i < Salt.Length; i++)
PlainTextWithSalt[i] = Salt[i];
for (long i = Salt.Length; i < PlainText.Length; i++)
PlainTextWithSalt[i] = PlainText.Value[i - Salt.Length];

// Generate the hash and return the result
byte[] HashBytes = Hash.ComputeHash(PlainTextWithSalt);
return new SqlBytes(HashBytes);
}
}
}

当我使用下面的代码从 SQL 执行测试时,会按预期为每个算法生成哈希。

DECLARE @plaintext varchar(15);
SET @plaintext = 'ABCDEFGHIJ';

DECLARE @salt varbinary(16);
SET @salt = Crypt_Gen_Random(16);

DECLARE @sha256 varbinary(32)
DECLARE @sha384 varbinary(48)
DECLARE @sha512 varbinary(64)

SELECT @sha256 = dbo.SaltedHash('SHA256', CAST(@plaintext AS varbinary(max)), @salt);
SELECT @sha384 = dbo.SaltedHash('SHA384', CAST(@plaintext AS varbinary(max)), @salt);
SELECT @sha512 = dbo.SaltedHash('SHA512', CAST(@plaintext AS varbinary(max)), @salt);

SELECT 'SHA-256' AS algorithm, @sha256 AS hash
UNION ALL
SELECT 'SHA-384', @sha384
UNION ALL
SELECT 'SHA-512', @sha512;

我想用它来验证登录,我假设我需要检索为用户记录存储的 salt 值并将它传递给 SaltedHash 函数,它会返回散列值.从那里,我会将函数返回的散列值与存储在用户记录中的散列值进行比较。

我遇到的问题是当我测试传递硬编码盐值('0x0E5ECC235FF6BD7337FFDDE5799D4EEA')以及明文('ABCDEFGHIJ')以模拟检索散列值(例如用于比较散列密码)时。如果我为 ('1234567890') 的纯文本值提供相同的硬编码盐值,它会返回完全相同的散列值。实际上,任何 10 个字符的明文值都会返回相同的散列值。

DECLARE @plaintext varchar(15);
SET @plaintext = 'ABCDE12345';

DECLARE @salt varbinary(16);
SET @salt = 0x0E5ECC235FF6BD7337FFDDE5799D4EEA; // Hardcoded salt value!

SELECT @salt

DECLARE @sha256 varbinary(32)
DECLARE @sha384 varbinary(48)
DECLARE @sha512 varbinary(64)

SELECT @sha256 = dbo.SaltedHash('SHA256', CAST(@plaintext AS varbinary(max)), @salt);
SELECT @sha384 = dbo.SaltedHash('SHA384', CAST(@plaintext AS varbinary(max)), @salt);
SELECT @sha512 = dbo.SaltedHash('SHA512', CAST(@plaintext AS varbinary(max)), @salt);

SELECT 'SHA-256' AS algorithm, @sha256 AS hash
UNION ALL
SELECT 'SHA-384', @sha384
UNION ALL
SELECT 'SHA-512', @sha512;

我假设问题在于“将明文与盐相结合”代码,但不确定。

关于如何解决这个问题有什么想法吗?

最佳答案

是的,你在数组复制时犯了一个错误,你从未将 PlainText 的最后一个 Salt.Length 字节复制到目标数组中。这是原始代码的更正版本。所有需要做的就是 i 需要上升到 PlainText.Length + Salt.Length

// Combine the plaintext with the salt
byte[] PlainTextWithSalt = new byte[PlainText.Length + Salt.Length];
for (long i = 0; i < Salt.Length; i++)
PlainTextWithSalt[i] = Salt[i];
for (long i = Salt.Length; i < PlainText.Length + Salt.Length; i++)
PlainTextWithSalt[i] = PlainText.Value[i - Salt.Length];

然而,使用 Array.Copy 会容易得多

byte[] PlainTextWithSalt = new byte[PlainText.Length + Salt.Length];
Array.Copy(Salt, PlainTextWithSalt, Salt.Length);
Array.Copy(PlainText, PlainTextWithSalt, Salt.Length, PlainText.Length);

还有一点要注意。加盐密码很好,但是 that is only half the battle ,您还需要使散列。通常这是通过 bcrypt 等函数完成的或 PBKDF2 ,这些函数为您管理盐和密码的混合,此外它们还允许您设置对密码进行散列的迭代次数(您通常会选择一个大数字,您希望数字尽可能大,这是您的终端系统可以容忍的因为速度慢)。

关于c# - 使用 SQL Server 2008 CLR 进行密码哈希处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19693615/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com