首页 > 解决方案 > 如何在 SQL SERVER 2016+ 中生成 SHA-3(256) 哈希

问题描述

如何在 SQL Server 2016 中生成 SHA-3 (256) 哈希?

HASHBYTES 似乎只能达到 SHA-2 (256) 或 SHA-2 (512)。

Microsoft BOL 并没有给我一个温暖和模糊的感觉,它是内置在任何地方的。

-- SHA2-256
DECLARE @HashThis nvarchar(32);  
SET @HashThis = CONVERT(nvarchar(32),'123456');  
SELECT HASHBYTES('SHA2_256', @HashThis);  

-- Output: 0xEC278A38901287B2771A13739520384D43E4B078F78AFFE702DEF108774CCE24

-- SHA3-256  (KECCAK)
DECLARE @HashThis nvarchar(32);  
SET @HashThis = CONVERT(nvarchar(32),'123456');  
SELECT HASHBYTES('SHA3_256', @HashThis);  

-- Output: NULL

标签: sqlsql-serverhash

解决方案


SQL Server CLR您可以通过集成实现 SHA-3 256 哈希

GitHub 上有一个项目已经为您完成了大部分工作,您可以轻松地为其添加 SHA3 支持。

https://github.com/sedenardi/sql-hashing-clr

纯 dotnet 核心无法进行 SHA3-256 散列。我建议您使用支持 SHA3-256 的 BouncyCastle 库 ( https://www.bouncycastle.org/csharp/index.html )。有一个 nuget 库包,它是 BouncyCastle 之上的一个包装器,可以使 SHA3-256 散列相对容易实现。https://www.nuget.org/packages/SHA3.Net/。你需要使用这个包并更新HashUtil.cs

先决条件:构建 CLR .dll

using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Security.Cryptography;
-- include NugetPackage to help with SHA-3 hashing

public class HashUtil
{
    [SqlFunction(IsDeterministic = true)]
    public static SqlBinary GetHash(SqlString algorithm, SqlBytes src)
    {
        if (src.IsNull)
            return null;

        switch (algorithm.Value.ToUpperInvariant())
        {
            case "MD5":
                return new SqlBinary(MD5.Create().ComputeHash(src.Stream));
            case "SHA1":
                return new SqlBinary(SHA1.Create().ComputeHash(src.Stream));
            case "SHA2_256":
                    return new SqlBinary(SHA256.Create().ComputeHash(src.Stream));
            case "SHA2_512":
                    return new SqlBinary(SHA512.Create().ComputeHash(src.Stream));
            -- add SHA3-256
            default:
                throw new ArgumentException("HashType", "Unrecognized hashtype: " + algorithm.Value);
        }
    }
}
  1. 将 CLR .dll 部署到 SQL Server

    此处参考微软关于如何部署 CLR .dll 的文档

    https://docs.microsoft.com/en-us/sql/relational-databases/clr-integration/deploying-clr-database-objects?view=sql-server-ver15

  2. 将函数部署到 SQL Server

    CREATE FUNCTION dbo.GetHashHybrid(@algorithm NVARCHAR(4000),@input VARBINARY(MAX))
     RETURNS VARBINARY(8000) WITH SCHEMABINDING
     AS
     BEGIN
     RETURN ( 
         SELECT dbo.GetHash(@algorithm,@input)
     )
     END
    
  3. 调用 dbo.GetHash

    DECLARE @INPUT VARCHAR(MAX);
    SELECT @INPUT = REPLICATE(CAST('test1' AS VARCHAR(MAX)),2000);
    SELECT dbo.GetHash('MD5',CONVERT(VARBINARY(MAX),@INPUT));
    

此示例显示 MD5 散列,但演示了如何使用 CLR 创建当前 SQL Server 不支持“开箱即用”的散列功能的概念。


推荐阅读