HASHBYTES: примеры (SQL)

Использование HASHBYTES в MS SQL для хеширования данных
Раздел: Функции безопасности и шифрования, Хеширование
HASHBYTES('algorithm', input): varbinary

Основные сведения о функции HASHBYTES

Функция HASHBYTES в Microsoft SQL Server предназначена для вычисления хеш-значения входных данных с использованием указанного алгоритма. Она часто применяется для создания контрольных сумм, проверки целостности данных, дедупликации записей или как часть механизмов шифрования.

Синтаксис функции: HASHBYTES ( 'algorithm', { @input | 'input' } )

Параметр algorithm определяет используемый алгоритм хеширования. Допустимые значения:

  • MD2, MD4, MD5 — алгоритмы семейства MD (Message Digest). MD5 возвращает 128-битный (16-байтный) хеш.
  • SHA — синоним для SHA1, возвращает 160-битный (20-байтный) хеш.
  • SHA1 — алгоритм Secure Hash Algorithm 1 (160 бит).
  • SHA2_256 — алгоритм SHA-2 с длиной хеша 256 бит (32 байта).
  • SHA2_512 — алгоритм SHA-2 с длиной хеша 512 бит (64 байта).

Параметр input задает данные для хеширования. Это может быть переменная, столбец или строковый литерал. Для типов данных, отличных от строковых, обычно требуется явное преобразование в VARBINARY или VARCHAR.

Возвращаемое значение имеет тип VARBINARY(max 8000 bytes). Максимальный размер входных данных зависит от версии SQL Server. В современных версиях (начиная с SQL Server 2016) ограничение снято для алгоритмов SHA2_256 и SHA2_512, для MD5 и SHA1 ограничение составляет 8000 байт.

Простые примеры использования

Пример с различными алгоритмами и строковым вводом:

SELECT
  HASHBYTES('MD5', 'Hello World') AS MD5_Hash,
  HASHBYTES('SHA1', 'Hello World') AS SHA1_Hash,
  HASHBYTES('SHA2_256', 'Hello World') AS SHA256_Hash;
MD5_Hash                                SHA1_Hash                                   SHA256_Hash
0x0A4D55A8D778E5022FAB701977C5D840BBC486D0 0x0A4D55A8D778E5022FAB701977C5D840BBC486D0 0xA591A6D40BF420404A011733CFB7B190D62C65BF0B...

Пример с преобразованием числа и даты:

SELECT HASHBYTES('SHA2_256', CAST(12345 AS VARCHAR(20)) + CAST(GETDATE() AS VARCHAR(30)));

Использование с двоичными данными:

DECLARE @bin VARBINARY(10) = 0x4D5353514C;
SELECT HASHBYTES('MD5', @bin) AS HashResult;

Похожие функции в MS SQL Server

CHECKSUM и BINARY_CHECKSUM — возвращают целочисленное значение контрольной суммы. Быстрее, чем HASHBYTES, но с большей вероятностью коллизий. Подходят для быстрой проверки изменений в строке, но не для криптографических задач.

CHECKSUM_AGG — агрегатная функция для вычисления контрольной суммы по группе значений.

SYSMESSAGES — не является прямой альтернативой, но иногда используется для хеширования в контексте шифрования (в сочетании с функциями типа ENCRYPTBYKEY).

Для криптографически стойкого хеширования следует использовать HASHBYTES с алгоритмами SHA2_256 или SHA2_512. Для быстрого сравнения данных в ETL-процессах иногда применяют CHECKSUM.

Аналоги функции в других СУБД и языках

MySQL: функция MD5(), SHA1(), SHA2(). SHA2 принимает второй аргумент — длину бит (224, 256, 384, 512).

SELECT MD5('text'), SHA1('text'), SHA2('text', 256);

PostgreSQL: функции md5(), sha1 (из расширения pgcrypto), digest() для различных алгоритмов.

SELECT md5('text'), encode(digest('text', 'sha256'), 'hex');

Oracle: пакет DBMS_CRYPTO с функцией HASH (поддерживает MD5, SHA1, SHA256, SHA384, SHA512).

SELECT UTL_RAW.CAST_TO_RAW(DBMS_CRYPTO.HASH(UTL_RAW.CAST_TO_RAW('text'), DBMS_CRYPTO.HASH_SH256)) FROM dual;

SQLite: отсутствуют встроенные функции хеширования, но можно использовать пользовательские функции через расширения.

Основное отличие MS SQL — единая функция HASHBYTES с выбором алгоритма через строковый параметр, в то время как другие СУБД часто имеют отдельные функции для каждого алгоритма.

Типичные ошибки

1. Превышение максимального размера входных данных для устаревших алгоритмов в старых версиях SQL Server.

-- Может вызвать ошибку в SQL Server 2014 и старше для больших текстов
SELECT HASHBYTES('MD5', REPLICATE('A', 9000));
Msg 8152, Level 16, State 10, Line 1
String or binary data would be truncated.

2. Неявное преобразование типов, приводящее к неожиданным результатам.

-- Хешируются разные представления
SELECT
  HASHBYTES('SHA2_256', '123') AS StrHash, -- строка '123'
  HASHBYTES('SHA2_256', CAST(123 AS VARBINARY)) AS NumHash; -- число 123

3. Использование устаревших алгоритмов MD5, SHA1 для задач, требующих криптографической стойкости.

4. Игнорирование чувствительности к регистру параметра алгоритма в некоторых версиях.

Изменения в последних версиях

В SQL Server 2016 снято ограничение в 8000 байт для входных данных алгоритмов SHA2_256 и SHA2_512. Теперь они поддерживают хеширование данных типа VARCHAR(max), NVARCHAR(max) и VARBINARY(max).

Алгоритмы MD2, MD4, MD5, SHA, SHA1 по-прежнему имеют ограничение в 8000 байт.

В SQL Server 2017 и более новых улучшена производительность для алгоритмов SHA2.

В будущих версиях возможно исключение устаревших алгоритмов (MD2, MD4, MD5, SHA1) из списка доступных по умолчанию.

Расширенные примеры применения

Создание детерминированного уникального идентификатора на основе нескольких полей для дедупликации:

Пример sql
WITH DataCTE AS (
  SELECT 'John' AS FirstName, 'Doe' AS LastName, CAST('1980-01-15' AS DATE) AS BirthDate
  UNION ALL
  SELECT 'Jane', 'Smith', '1992-05-30'
)
SELECT
  *,
  HASHBYTES('SHA2_256',
    CONCAT(FirstName, '|', LastName, '|', CAST(BirthDate AS VARCHAR(10)))
  ) AS RowHash
FROM DataCTE;

Сравнение хешей для обнаружения изменений в данных (техника медленно изменяющихся измерений Type 1):

Пример sql
-- Предположим, есть таблица-источник Source и целевая таблица Dimension
MERGE Dimension AS target
USING (
  SELECT
    ID,
    HASHBYTES('SHA2_256',
      CONCAT(Field1, Field2, Field3)
    ) AS SourceHash
  FROM Source
) AS source
ON target.ID = source.ID
WHEN MATCHED AND target.StoredHash <> source.SourceHash
THEN UPDATE SET
  target.Field1 = source.Field1,
  target.Field2 = source.Field2,
  target.StoredHash = source.SourceHash,
  target.ModifiedDate = GETDATE();

Использование в сочетании с цифровой подписью (через функции шифрования):

Пример sql
-- Создание хеша для подписи
DECLARE @document NVARCHAR(100) = N'Важный контракт №12345';
DECLARE @hash VARBINARY(64) = HASHBYTES('SHA2_512', @document);
-- @hash может быть затем передан в функцию ENCRYPTBYASYMMKEY для подписи

Построение иерархических хешей для больших документов (техника "Merkle Tree"):

Пример sql
-- Разбиение текста на части и вычисление общего хеша
DECLARE @text NVARCHAR(MAX) = N'Очень длинный текст...';
DECLARE @part1 NVARCHAR(4000), @part2 NVARCHAR(4000);
SET @part1 = SUBSTRING(@text, 1, 4000);
SET @part2 = SUBSTRING(@text, 4001, 4000);

SELECT
  HASHBYTES('SHA2_256',
    CONCAT(
      HASHBYTES('SHA2_256', @part1),
      HASHBYTES('SHA2_256', @part2)
    )
  ) AS TotalHash;

Генерация короткого уникального кода на основе хеша (обрезание):

Пример sql
SELECT
  LEFT(MASTER.dbo.fn_varbintohexstr(HASHBYTES('MD5', 'example@email.com')), 8) AS ShortCode;
-- Возвращает первые 8 символов шестнадцатеричного представления

MS SQL HASHBYTES function comments

En
HASHBYTES Returns the hash of the input value