我正在嘗試使用SHA-512算法實現SQL Server 2008中的散列和密碼解決方案。此解決方案基於Michael Coles出版的書籍「Expert SQL Server 2008 Encryption」。基於他的例子,我能夠在Visual Studio 2010(C#中的.NET 3.5)中構建項目並部署到SQL Server 2008(如下面的代碼所示)。使用SQL Server 2008密碼散列CLR
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;
我想用這個驗證登錄,在這裏我假設我需要檢索存儲在用戶記錄中的鹽值並將其傳遞到SaltedHash功能,哪裏會返回哈希值。從那裏,我將比較函數返回的哈希值和存儲在用戶記錄中的哈希值。
我遇到的問題是當我測試傳遞一個硬編碼鹽值('0x0E5ECC235FF6BD7337FFDDE5799D4EEA'),以及明文('ABCDEFGHIJ')模擬檢索哈希值(例如比較散列密碼)。如果我使用相同的硬編碼salt值提供明文值('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;
我假設問題在於「結合明文與鹽」的代碼,但不確定。
有關如何解決此問題的任何想法?
請注意,如果鹽在您的最終解決方案中進行了硬編碼,則它不是鹽。這將是一個[Pepper],鹽每個密碼都是唯一的,你通常會只需將salt存儲在下一列中,或將其連接到密文字節陣列的前面或後面。 –
謝謝你的提示,因爲我不熟悉'胡椒'。我的意圖是按照您的建議爲每個密碼創建一個獨特的salt。 – vanexellent