sql - 如何在 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
解决方案
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);
}
}
}
将 CLR .dll 部署到 SQL Server
此处参考微软关于如何部署 CLR .dll 的文档
将函数部署到 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
调用 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 不支持“开箱即用”的散列功能的概念。
推荐阅读
- sql - Oracle SQL 对相互连接的两个列值进行排序
- c# - 跟踪使用矩阵变换 C# Winforms 的多个对象
- vim - VSCode Vim 多个游标
- python - pytest 可以忽略特定警告吗?
- c# - System.AggregateException:发生一个或多个错误。(一个任务被取消了。)
- reactjs - 如何将 React 应用程序从 Github 部署到设置了环境变量的 AWS S3 存储桶注意:我没有在 github 中推送 .env 文件
- java - .jar 中没有主要清单属性
- docker - 如何在 docker 映像中增加 activeMQ 的堆内存
- powershell - 仅将新文件移动到其他目录 - Powershell
- sorbet - 使用 bundler 和 dependabot 生成 Sorbet RBI 文件