Поиск зашифрованных данных в SQL Server может быть сложной задачей. После шифрования данных становится сложно эффективно искать конкретные значения без дополнительных изменений. В этой статье мы рассмотрим использование кодов аутентификации сообщений (MAC) для преодоления этой проблемы.
Коды аутентификации сообщений – это особое использование общего термина, используемого для обмена сообщениями. В отличие от шифрования, хеширование всегда возвращает одинаковый шифротекст для заданного входного значения. Например, если мы запустим код SELECT HashBytes('MD5', 'secret')
, мы всегда получим одинаковый шифротекст: 0x5EBE2294ECD0E0F08EAB7690D2A6EE69
. Эта последовательность позволяет нам выполнять эффективные поиски, сначала хешируя искомое значение, а затем находя записи, которые соответствуют хешированному значению.
Однако использование хеширования для поиска может иметь потенциальную уязвимость. Поскольку хеширование всегда возвращает одинаковый шифротекст, злоумышленник может запустить атаку по словарю против таблицы и найти значения, которые соответствуют заданной строке. Для смягчения этого риска мы можем использовать “соль”. Шифруя соль и затем добавляя ее к строке, которую мы пытаемся сохранить, злоумышленник не может просто хешировать набор значений и сравнивать шифротекст с результатом.
При реализации MAC в SQL Server важно учитывать длину соли и точную длину хешированного значения. Рекомендуется создать пользовательский тип данных (UDT), который позволяет некоторую вариацию в длине секрета, а не раскрывать точную длину в вашем коде.
Давайте рассмотрим простой пример, чтобы продемонстрировать использование MAC в SQL Server:
CREATE TABLE dbo.SecretSalt (
SaltID tinyint NOT NULL,
Salt varbinary(100) NOT NULL CONSTRAINT SecretSalt_PK PRIMARY KEY CLUSTERED (SaltID)
);
CREATE TABLE dbo.Hash1 (
RecordID int NOT NULL,
EncryptResult varbinary(116) NOT NULL,
HashResult varbinary(20) NOT NULL,
CONSTRAINT Hash1_PK PRIMARY KEY CLUSTERED (RecordID)
);
-- Добавить запись соль
INSERT INTO dbo.SecretSalt (SaltID, Salt)
SELECT 1, EncryptByKey(Key_GUID('TestKey1'), 'd=s_4ZeG3me4E#U4ru6ag&@ru@A2Afr7');
-- Добавить записи в Hash1
DECLARE @string1 varchar(50);
DECLARE @ct int = 1;
WHILE @ct <= 10
BEGIN
SET @string1 = 'Simple' + CONVERT(varchar(11), @ct);
INSERT INTO dbo.Hash1 (RecordID, EncryptResult, HashResult)
VALUES (@ct, EncryptByKey(Key_GUID('TestKey1'), @string1), HashBytes('SHA1', @string1));
SET @ct = @ct + 1;
END;
-- Найти одну запись
DECLARE @lookUp int;
SET @lookUp = 5;
SELECT h.RecordID, CONVERT(int, CONVERT(varchar(11), DecryptByKey(h.EncryptResult))) AS 'Decrypted Value'
FROM dbo.Hash1 AS h
CROSS JOIN dbo.SecretSalt AS s
WHERE s.SaltID = 1
AND h.HashResult = HashBytes('SHA1', CONVERT(varchar(63), DecryptByKey(s.Salt)) + CONVERT(varchar(11), @lookUp))
AND CONVERT(int, CONVERT(varchar(11), DecryptByKey(h.EncryptResult))) = @lookUp;
В этом примере мы создаем две таблицы: SecretSalt
для хранения значения соли и Hash1
для хранения зашифрованных и хешированных записей. Затем мы добавляем запись соль и несколько примеров записей в Hash1
. Наконец, мы выполняем поиск одной записи, которая соответствует ожидаемой строке.
Важно отметить, что у MAC есть ограничения. Они поддерживают только поиск точных совпадений и не поддерживают диапазонные запросы или подстановочные символы. Кроме того, использование MAC не гарантирует защиту от коллизий хешей. Все равно необходимо проверить, соответствует ли зашифрованное значение искомому значению.
В следующей статье мы обсудим результаты производительности комбинирования шифрования и хеширования в SQL Server. Следите за обновлениями!
Ссылки:
- SQL Server 2005: поиск зашифрованных данных
- Использование хеширования для сокрытия конфиденциальных данных
Что вы думаете? Если у вас есть отзывы или предложения, пожалуйста, поделитесь ими в комментариях ниже.