История про хитрожо… индуса, encrypted procedures, DAC и «режим Бога»
На той неделе пришлось разбираться в логике работы одного бесплатного тула. Почти детективная история вышла с ее автором, который впоследствии оказался индусом канадского происхождения проживающим в Южной Америке.
Конечно же, практическая ценность была не в биографии автора, а в запросах, которые отправлялись приложением на сервер.
Установил. Запустил. Стал в стоечку и начал собирать профайлером все, чем приложение должно было «порадовать» сервер. Смею разочаровать – ничего радостного сервер в ближайшие два часа не увидел. В основном встречались разного рода перлы в запросах, которые явно не претендовали на комплименты:
Поскольку их можно написать на порядок проще и сократить логические чтения из таблицы:
На этом можно было бы и закончить… Но практически под конец я увидел, что приложение вызывает пользовательские хранимые процедуры из tempdb. Поймал себя на мысли: «Когда приложение успело их создать… и главное зачем?»
Оказывается, инсталлятор по-тихому нашел дефолтный экземпляр SQL Server на моей локальной машине и создал там хранимки. Попробовал поработать с данным тулом на именованном инстансе… Error Message!
Архитектурное решение на грани фантастики. К слову скажу, при каждом рестарте сервера база tempdb пересоздаётся… так что ж мне программу каждый раз переустанавливать? Бред! Бред… как сказал бы мой попугай.
Оки… Развернем эти хранимки на именованном сервере, а заодно посмотрим, что в них такого ценного. Открываем хранимые процедуры в Database Explorer и видим «картину маслом»:
Замочек на объектах… а значит хранимые процедуры созданы с параметром WITH ENCRYPTION и сгенерировать в SSMS команду CREATE или ALTER уже не получится:
Property TextHeader is not available for StoredProcedure ‘[dbo].[shb_get_waitstats’]’. This property may not exist for this object, or may not be retrievable due to insufficient access rights. The text is encrypted.
В метаданных мы тоже не сможем получить сорс зашифрованных объектов:
Такой лайвфак лайвхак также не сработает:
Переустанавливать приложение не хотелось и поэтому решил схитрить. Включаем «режим Бога», который разрешает подключаться к серверу через DAC (Dedicated Administrator Connection):
Вначале соединения в SQL документе дописываем ADMIN: и проверяем что пользователь под которым мы коннектимся является sysadmin-ом:
Если соединение пройдет успешно, то мы будем имеем абсолютную власть на сервером. Но что на практике поменяется? Ведь мы и так имеем права sysadmin, которые разрешают все что только можно.
Как оказывается, ограничение все же есть. Пробовали ли хоть раз читать из системных таблиц? В SQL Server 2000 такое поведение разрешалось. С приходом же 2005 версии секьюрность метаданных претерпела существенные изменения и доступа к системных таблицам напрямую теперь уже нет.
В основном к таблицам с метаданными можно обращаться неявно, посредством системных представлений, которых в 99% случаев бывает достаточно. Но не в нашем случае. Существует отдельная таблица sys.sysobjvalues в которой хранятся зашифрованные объекты:
В обычных условиях читать из нее нельзя:
но при подключении через DAC становится возможным выборка из любой системной таблицы и из нее в частности:
Имея на руках зашифрованное тело хранимой процедуры можно ее расшифровать…
Для начала мы получаем бинарное представление хранимки в зашифрованном виде. Создаем заготовку хранимки с идентичным именем и параметром WITH ENCRYPTION, но вместо тела подставляем символы дефисов:
Далее используя XOR преобразование над полученными строками, мы можем расшифровать требуемый объект:
Можно легко проверить все на простом примере:
Все вроде кажется таким элементарным, но что если нет возможности подключиться через DAC? Или требуется расшифровать скалярную функцию или представление… Есть вариант использовать самописную CLR сборку, которую можно поискать на CodeProject или воспользоваться уже готовыми решениями.
К слову о последнем варианте… Уже давно существует бесплатный продукт – dbForge SQL Decryptor, который позволяет в пакетном режиме расшифровывать все скриптовые объекты:
И что самое главное, для его работы не требуется DAC подключение. Мне стало очень интересно, как без использования DAC выбрать данные из системной таблицы… оказалось все очень просто. Вначале SQL Decryptor получает список страниц, на которых хранятся данные из sys.sysobjvalues:
Потом обходит все страницы:
Смотрит на их содержимое:
И по нему достает бинарное представление объектов в зашифрованном виде. А дальше Вы уже знаете, как происходит – простое XOR преобразование.
Что сказать по данному поводу? Если Вам нужно автоматизировать процесс расшифровки объектов, то можно написать скрипт по аналогии с моим решением. Но в большинстве случаев будет достаточно просто запустить dbForge SQL Decryptor, выбрать объект и получить его сорс:
После этого CodeReview я пообщался с индусом. Он выслушал все мои замечания по части найденных проблем с запросами и больше уже больше не выходил на связь… Вот такая выдалась продуктивная неделя.
Шифрование столбца данных
В этой статье описывается шифрование столбца данных симметричным шифрованием в SQL Server с помощью Transact-SQL. Иногда это называется шифрованием на уровне столбца или ячейки. Эта функция доступна в виде предварительной версии для Azure Synapse Analytics.
Примеры в этой статье проверены с помощью AdventureWorks2017. Чтобы получить примеры баз данных, см. статью Примеры баз данных AdventureWorks.
Безопасность
Разрешения
Для выполнения приведенных ниже шагов необходимы следующие разрешения.
Создание главного ключа базы данных
Для применения приведенных ниже примеров требуется главный ключ базы данных. Если в базе данных еще нет главного ключа базы данных, создайте его. Для этого подключитесь к базе данных и выполните следующий скрипт. Обязательно используйте сложный пароль.
Скопируйте и вставьте следующий пример в окно запроса, подключенное к примеру базы данных AdventureWorks. Нажмите кнопку Выполнить.
Всегда создавайте резервную копию главного ключа базы данных. Дополнительные сведения о создании главных ключей баз данных см. в статье CREATE MASTER KEY (Transact-SQL).
Пример Шифрование с помощью симметричного шифрования и структуры проверки подлинности
В обозревателе объектов подключитесь к экземпляру компонента Компонент Database Engine.
На стандартной панели выберите пункт Создать запрос.
Скопируйте и вставьте следующий пример в окно запроса, подключенное к примеру базы данных AdventureWorks. Нажмите кнопку Выполнить.
Шифрование с помощью простого симметричного шифрования
В обозревателе объектов подключитесь к экземпляру компонента Компонент Database Engine.
На стандартной панели выберите пункт Создать запрос.
Скопируйте и вставьте следующий пример в окно запроса, подключенное к примеру базы данных AdventureWorks. Нажмите кнопку Выполнить.
Дополнительные сведения см. в следующих разделах:
Шифрование SQL Server
Шифрование представляет собой способ скрытия данных с помощью ключа или пароля. Это делает данные бесполезными без соответствующего ключа или пароля для дешифрования. Шифрование не решает проблемы управления доступом. Однако оно повышает защиту за счет ограничения потери данных даже при обходе системы управления доступом. Например, если компьютер, на котором установлена база данных, был настроен неправильно и злоумышленник смог получить конфиденциальные данные, то украденная информация будет бесполезна, если она была предварительно зашифрована.
Несмотря на то, что шифрование является полезным средством обеспечения безопасности, его не следует применять ко всем данным или соединениям. При решении о внедрении шифрования необходимо проанализировать, как пользователи получают доступ к данным. Если пользователи получают доступ к данным через открытую сеть, то шифрование может потребоваться для повышения безопасности. Однако если весь доступ осуществляется по безопасной внутренней сети, то шифрование не требуется. Использование шифрования включает политику управления паролями, ключами и сертификатами.
Последние сведения о безопасности уровня транспорта (TLS1.2) см. в статье Поддержка TLS 1.2 для Microsoft SQL Server.
В SQL Server можно шифровать соединения, данные и хранимые процедуры. В следующих разделах содержатся дополнительные сведения о шифровании в SQL Server.
Иерархия средств шифрования
Сведения об иерархии шифрования в SQL Server.
Выбор алгоритма шифрования
Сведения о выборе эффективного алгоритма шифрования.
Прозрачное шифрование данных (TDE)
Общие сведения о прозрачном шифровании данных.
Ключи шифрования базы данных и SQL Server (ядро СУБД)
Используемые в SQL Serverключи шифрования представляют собой сочетание открытых, закрытых и симметричных ключей, которые используются для защиты конфиденциальных данных. В этом разделе рассказывается о внедрении и управлении ключами шифрования.
Постоянное шифрование (компонент Database Engine)
Предотвращение доступа локальных администраторов баз данных, операторов облачных баз данных и других неавторизованных пользователей с высоким уровнем привилегий к зашифрованным данным.
Маскирование динамических данных
Ограничение возможности раскрытия конфиденциальных данных за счет маскирования этих данных для непривилегированных пользователей.
Сертификаты SQL Server и асимметричные ключи
Сведения об использовании шифрования с открытым ключом.
См. также
Обеспечение безопасности SQL Server
Общие сведения о способах обеспечения безопасности платформы SQL Server и способах работы с пользователями и защищаемыми объектами.
Обзор возможностей системы безопасности Базы данных SQL Azure
Общие сведения о системе безопасности Базы данных SQL Azure, которая обеспечивает защиту данных, контроль доступа и возможности упреждающего мониторинга.
ENCRYPTBYPASSPHRASE (Transact-SQL)
Сведения об использовании паролей для шифрования данных.
ENCRYPTBYKEY (Transact-SQL)
Сведения об использовании симметричных ключей для шифрования данных.
ENCRYPTBYASYMKEY (Transact-SQL)
Сведения об использовании асимметричных ключей для шифрования данных.
ENCRYPTBYCERT (Transact-SQL)
Сведения об использовании сертификатов для шифрования данных.
Базу данных не стащить: правильные способы защитить данные в таблицах БД
Содержание статьи
Как же ошибаются те люди, которые доверяют защиту данных исключительно самой
СУБД. Мол, если пароль на подключение хороший и версия демона – самая последняя,
то все будет нормально. Ничего подобного. Базы как сливали, так и будут сливать.
А наша задача – сделать их нечитаемыми для тех, кому они не предназначены.
Актуальная проблема из мира информационной безопасности – обеспечить
сохранность данных. Есть ситуации, в которых даже при наличии серьезной защиты
системы, сохранность данных оказывается под большим вопросом. Как так? Могу
привести пример из личного опыта, когда в разглашении информации был виновен
засланный сотрудник конкурирующей компании. Находясь на рабочем местом и будучи
технически подкованным, он взламывал сервера баз данных банальным брутфорсом
через терминальное соединение. Базы с клиентами «засланец» перепродавал другим
компаниям, а «интересная» информация о ведении бизнеса отправлялась сотрудникам
силовых структур. Что из этого вышло, объяснять излишне.
Вообще, имея физический доступ к локальной сети, инсайдер мог поступить
гораздо проще: атаковать программу, которая работает с базой данных. Нередко
сценарий взлома сводится к тому, что из программы разными способами извлекаются
конфиги для подключения к базе. Захватив ту же 1С, которая хранит в себе конфиги
подключения к базе (в том числе, шифрованный обычным XOR’ом пароль),
злоумышленник получает доступ к самой базе. Особо не стесняясь, он может ее
выкачать, модифицировать или просто удалить. Такая брешь в защите способна
сыграть злую шутку, особенно в корпоративной среде.
В статье я как раз хочу рассказать о том, как обезопасить информацию в
обычной базе данных. Даже если СУБД будет взломана или левый человек скопирует
данные, утечки конфиденциальной информации не произойдет!
Шифрованию – быть!
Общий подход прост до гениального: раз злоумышленник гипотетически сможет
извлечь данные, надо сделать так, чтобы он их не смог прочитать. Информацию все
равно придется хранить в базе, но… ничего не мешает хранить ее в каком угодно
виде, в том числе зашифрованном! Главное, чтобы мы сами потом смогли
расшифровать :).
Компания Spelabs (www.spellabs.ru/spellabsCrypto1C.htm)
как-то анонсировала продукт, организующий дополнительную безопасность
бухгалтерских 1С на уровне шифрования данных, причем на полностью прозрачном
уровне. Пользовательские приложения, не подозревая о надстройке, работали в
обычном режиме. Увы, компания прекратила разработку этого направления. Но
реально обойтись и без подобных инструментов, ведь для шифрования сгодятся даже
штатные средства СУБД!
Любая современная СУБД, если это, конечно, не собранная на коленке курсовая,
может похвастаться достаточно надежными механизмами шифрования данных. В той же
самой MySQL я по памяти насчитал около 14 соответствующих функций, которые тебе
наверняка хорошо известны:
Для их применения надо лишь чуть изменить свои SQL-запросы, добавив в нужном
месте функции AES_ENCRYPT() или DES_ENCRYPT(), которые считаются наиболее
надежными в MySQL на текущий момент. Например, так:
INSERT INTO t VALUES (1,AES_ENCRYPT(‘text’,’password’));
Приятно признать, что хорошие программисты эти функции используют. Часто во
время проведения SQL-инжекции мне приходилось ломать голову и определять
функцию, которую использовал кодер для крипточки данных. В результате, требуется
производить те же AES_DECRYPT(AES_ENCRYPT()) наряду с unhex(hex()).
Помимо симметричного шифрования, когда упаковка и распаковка текста
производятся одним и тем же ключом (общим для двух участников обмена
сообщениями), поддерживается и ассиметричное криптование. Идея ассиметричных
алгоритмов подразумевает наличие двух ключей – открытого и закрытого
(секретного). Один из них используется для шифрования информации, а другой — для
дешифрования. Если кодирование осуществляется с помощью открытого ключа, то
расшифровать такие данные можно только с помощью парного ему закрытого.
Предлагаю разобраться с этим на примере Microsoft SQL Server, который часто
используется в корпоративных порталах и сложных приложениях.
Для шифрования применяются функции T-SQL, представляющие собой специальное
дополнение языка SQL. Оно поддерживает управляющие операторы, локальные
переменные и различные дополнительные функции.
USE Bank;
CREATE CERTIFICATE andrej
ENCRYPTION BY PASSWORD = ‘pGFD4bb925DGvbd2439587y’
# Для генерации с использованием подгрузки из файла
# FROM FILE = ‘c:\Shipping\Certs\Shipping11.cer’
# WITH PRIVATE KEY (FILE = ‘c:\Shipping\Certs\Shipping11.pvk’,
WITH SUBJECT = ‘Employers Access’,
EXPIRY_DATE = ’10/31/2009′;
GO
У нас создался сертификат! Теперь его можно без проблем использовать для
размещения в таблице зашифрованных записей, выполняя привычные SQL-запросы:
INSERT INTO [БАЗА].[ТАБЛИЦА]
values( N’ДАННЫЕ ДЛЯ ЗАШИФРОВКИ’,
EncryptByCert(Cert_ID(‘andrej’), @cleartext) );
GO
В этом примере неформатированный текст из переменной @cleartext шифруется
сертификатом с именем «andrej». Зашифрованные данные помещаются в таблицу
«ТАБЛИЦА». Уточню, что данные могут быть расшифрованы только с помощью
соответствующего закрытого ключа (как уже было сказано, «приватного»).
Имя функции для обратного преобразования угадать несложно: DecryptByCert(). А
вот синтаксис более хитер, и с ним все чуть сложнее. Дело в том, что на
приватный ключ, как правило, закладывается дополнительный пароль (passphrase).
Его необходимо ввести, и по этой причине он обязательно будет присутствовать в
коде запроса или процедуры. Это не очень хорошо, потому что в этом случае его
можно быстро увести. Но с этим мы разберемся позже, когда поговорим о
безопасности хранимых процедур. А пока – код для извлечения данных из
шифрованной базы данных:
SELECT convert(nvarchar(max), DecryptByCert(Cert_Id(‘andrej’),
ProtectedData, N’pGFD4bb925DGvbd2439587y’))
FROM [БАЗА].[ТАБЛИЦА]
WHERE Description
= N’Employers Access’;
GO
В этом примере производится выборка строк из таблицы [БАЗА].[ТАБЛИЦА],
помеченных как «Employers Access». Пример дешифрует зашифрованный текст с
помощью закрытого ключа сертификата «Andrej» и дополнительного пароля
pGFD4bb925DGvbd2439587y. Расшифрованные данные преобразуются из типа varbinary в
тип nvarchar.
Надо сказать, что ассиметричные преобразования гораздо более накладны, чем
шифрование и дешифрование с использованием симметричного ключа. Поэтому
использование ассиметричного шифрования не рекомендуется при работе с большими
объемами данных, например, таблицами пользовательских данных. Это важно
учитывать при особо больших базах, а также базах, структура которых не приведена
к одной из нормальных форм.
Прячем хранимые процедуры!
Если ты не заметил, многое упирается в то, что вся конфиденциальность и
целостность завязана на использование хранимых процедур или функций. Получается,
что, получив к ним доступ и грамотно проанализировав их код, любой опытный хакер
сможет преобразовать шифрованную белиберду в исходный текст. Конечно, добраться
до кода процедур далеко не всегда реально, потому здесь всплывает вопрос об
утечке программной начинки производства, а именно – логике ПО. Но именно по этой
причине необходимо прибегать к шифрованию процедур и функций в базе. Одно из
самых популярных и удачных средств для таких действий – это программа SQL Shield
(www.sql-shield.com).
После несложной установки приложения не забудь указывать дополнительный флаг
/*sqlshield*/ с выражением «WITH ENCRYPTION» всякий раз, когда будешь создавать
защищенную процедуру. Вот пример функции, которая исполняет простейший запрос к
базе:
CREATE PROCEDURE MyTest
WITH /*sqlshield*/ ENCRYPTION
AS
SELECT 2+2
Исполняем процедуру и получаем:
Проверим, в каком виде хранится процедура, с помощью специального средства
для ковыряния в файлах базы. Подойдет SQL Server Syscomments Decryptor (www.geocities.com/d0mn4r/dSQLSRVD.html),
который при отображении текста процедуры показывает одни лишь знаки вопроса.
Все работает!
Как облегчить себе жизнь?
В заключение – не менее интересный продукт XP_CRYPT (www.xpcrypt.com).
Это средство осуществляет весь тот геморрой, который мы только что проделали
вручную. Все, что от тебя требуется, – скачать дистрибутив проги, установить ее
на сервер (к сожалению, есть версия только для Винды), обозначить свою базу
данных и начать химию с таблицами с помощью удобного GUI-интерфейса.
Напишем внешнюю функцию UDF (расшифровывается, как «User-Defined-Function»,
подробности) для преобразования строки в SHA-хеш:
CREATE FUNCTION ud_MakeSHA1 (@clearpass VARCHAR (8000) )
RETURNS VARCHAR (40)
AS
BEGIN
DECLARE @ret as VARCHAR(40)
EXEC master..xp_sha1 @clearpass,@ret OUTPUT
RETURN @ret
END
Отдаем команду: UPDATE tbl_CCards SET password = dbo.ud_MakeSHA1(Password).
После чего еще раз проверяем содержимое базы той же командой. Что видим? Все
зашифровано, все пароли захешировались!
Теперь нужно не забыть о том, что мы используем шифрование при обращении к
базе. В нашем случае, когда ты будешь делать авторизацию пользователей,
процедура проверки пароля по хешу будет выглядеть примерно так:
CREATE FUNCTION ud_CheckUser (@username VARCHAR(16),@clear_pass VARCHAR
(16))
RETURNS INTEGER
AS BEGIN
DECLARE @res INTEGER
SELECT @res = count(*) FROM tbl_CCards where username=@username AND
password=dbo.ud_MakeSHA1(@clear_pass)
IF @res > 1 SELECT @res= 0
RETURN @res
END
Проверяем исполнением команды:
SELECT dbo.ud_CheckUser (‘anna’,’kolbaska’)
>1 (неправильно)
SELECT dbo.ud_CheckUser (‘anna’,’love’)
>0 (окейно!)
К шифрованию номера кредитной карты надо подойти более серьезно. Впрочем, мы
не будем вникать в различного рода стандарты по информационной безопасности в
платежно-карточной сфере (вроде PCI; хотя организации, работающие с кредитными
картами, безусловно обязаны это делать). В бесплатной версии XP_CRYPT существует
возможность генерации только 256-битного ключа RSA. Вот этим и можно
воспользоваться (пусть упомянутый стандарт и требует, как минимум, 768-битного
ключа). Я бы мог сейчас привести код по генерации публичного и приватного ключа,
но… поступим проще. Все действия можно выполнить из понятного графического
интерфейса, и во многих случаях оставить все на совести программы, не написав ни
строчки кода. И поверь, будет работать!
Пример из личного опыта
Сотрудниками одной из компаний платежно-карточного сектора велась база данных
для выдачи зарплат. Для простого понимания, – пусть это будет примерно следующая
структура:
ID LastName FirstName Emp
Sum
354 Somov Oleg
IT-Manager M0x8900f56543
643 Antipova Alexandra Director
4343Lax#dsdsss
411 Timurov Valeriy Technical Dep.
0x2322322222
Выборку из базы я привел абсолютно произвольную, а теперь суть идеи.
«Безопасниками» компании было предпринято вполне благородное решение – шифровать
данные о зарплатах, которые очень часто бывают «серыми». Инсайдер получил доступ
к базе и сильно обломался, заимев информацию в таком виде. Однако, он не
отчаялся и проделал следующий фокус. Резонно предположив, что человек с
должностью директора должен получать больше, чем простой менеджер, он поменял
соответствующие поля со значениями зарплат одно на другое, тем самым – подложив
бухгалтерскому отделу абсолютно левую информацию. В благополучный день такая
вещь прокатила, и все безопасники были уволены. Для справки: этим сотрудником
был не я, как впрочем, и не безопасником.
Так делать не стоит
В SQL Server можно создавать четыре типа объектов (хранимые процедуры,
представления, пользовательские функции и триггеры) с параметром WITH
ENCRYPTION. Этот параметр позволяет зашифровать определение объекта таким
образом, что тот можно будет использовать, но получить его определение
стандартными способами станет невозможно. Это средство рекомендуется и
Microsoft. К сожалению, на практике никакой защиты применение стандартных
средств шифрования не обеспечивает! Алгоритм, используемый при шифровании
определений объектов, выглядит так:
У этой схемы есть два слабых места:
Как можно расшифровать зашифрованные объекты на SQL Server? Есть два
варианта:
Always Encrypted
Always Encrypted — это функция, предназначенная для защиты конфиденциальных данных, таких как номера кредитных карт или номера документов (например, номеров социального страхования в США), которые хранятся в базах данных База данных SQL Azure и SQL Server. Постоянное шифрование позволяет клиентам шифровать конфиденциальные данные в клиентских приложениях, не раскрывая ключи шифрования Компонент Database Engine (База данных SQL или SQL Server). Таким образом, постоянное шифрование позволяет разделить пользователей на тех, кто владеет данными или имеет право их просматривать, и тех, кто управляет данными, но не должен иметь к ним доступа. У локальных администраторов баз данных, операторов облачных баз данных и других неавторизованных пользователей с высоким уровнем привилегий нет доступа к зашифрованным данным, поэтому постоянное шифрование позволяет клиентам хранить конфиденциальные данные вне сферы их непосредственного контроля. При этом организации могут хранить данные в Azure, делегировать права администратора локальной базы данных третьим лицам или упростить требования к безопасности для собственных администраторов базы данных.
Always Encrypted предоставляет возможности конфиденциальных вычислений, позволяя Компонент Database Engine обрабатывать некоторые запросы к зашифрованным данным, при этом сохраняя конфиденциальность данных и предоставляя указанные выше преимущества безопасности. В SQL Server 2016 (13.x);, SQL Server 2017 (14.x); и База данных SQL Azure Always Encrypted поддерживает сравнение на равенство через детерминированное шифрование. См. раздел Выбор детерминированного или случайного шифрования.
В SQL Server 2019 (15.x) безопасные анклавы существенно расширяют возможности конфиденциальных вычислений Always Encrypted с помощью сопоставления шаблонов, других операторов сравнения и шифрования на месте. См. раздел Always Encrypted с безопасными анклавами.
Постоянное шифрование делает шифрование прозрачным для приложений. Драйвер с поддержкой постоянного шифрования, установленный на клиентском компьютере, реализует это за счет автоматического шифрования и расшифровки конфиденциальных данных в клиентском приложении. Драйвер шифрует данные из конфиденциальных столбцов перед их передачей в Компонент Database Engineи автоматически переписывает запросы, чтобы сохранить семантику приложения. Аналогичным образом драйвер прозрачно расшифровывает данные, которые хранятся в зашифрованных столбцах базы данных в результатах запроса.
Always Encrypted доступен во всех выпусках База данных SQL Azure, начиная с SQL Server 2016 (13.x);, и всех уровней служб База данных SQL. (До версии SQL Server 2016 (13.x); SP1 шифрование Always Encrypted было ограничено выпуском Enterprise Edition.) Презентацию с описанием постоянного шифрования на канале 9 см. на странице Безопасное хранение конфиденциальных данных с помощью постоянного шифрования.
Типичные сценарии
Клиент и данные в локальной среде
Клиент в локальной среде, а данные в Azure
Клиент и данные в Azure
У клиента есть клиентское приложение, размещенное в Microsoft Azure (например, рабочая роль или веб-роль), которое работает с конфиденциальными данными, хранящимися в базе данных, размещенной в Azure (базе данных SQL или SQL Server в виртуальной машине Microsoft Azure). Несмотря на то, что Always Encrypted не обеспечивает полной изоляции данных от облачных администраторов, поскольку и данные, и ключи доступны администраторам облака на платформе, где размещен клиентский уровень, клиент все равно извлекает преимущества из уменьшения площади поверхности атак на систему безопасности (данные в базе данных всегда зашифрованы).
Принцип работы
Можно настроить постоянное шифрование для отдельных столбцов базы данных, которые содержат ваши конфиденциальные данные. При настройке шифрования для столбца вы указываете сведения об алгоритме шифрования и криптографических ключах, используемых для защиты данных в столбце. В технологии постоянного шифрования используются два типа ключей: ключи шифрования столбца и главные ключи столбца. Ключ шифрования столбца используется для шифрования данных в зашифрованном столбце. Главный ключ столбца — это ключ защиты ключа, который шифрует один или несколько ключей шифрования столбца.
Компонент Database Engine сохраняет конфигурацию шифрования для каждого столбца в метаданных базы данных. Отметим, однако, что Database Engine никогда не сохраняет и не использует ключи какого-либо из этих типов в форме обычного текста. Здесь только хранятся зашифрованные значения ключей шифрования столбцов и информация о расположении главных ключей столбца, которые хранятся во внешних доверенных хранилищах ключей, например Azure Key Vault или хранилище сертификатов Windows на клиентском компьютере, либо в аппаратном модуле безопасности.
Для доступа к данным, сохраненным в зашифрованном столбце в виде обычного текста, в приложении необходимо использовать клиентский драйвер с включенным постоянным шифрованием. Если приложение отправляет параметризованный запрос, драйвер прозрачно взаимодействует с Database Engine, чтобы определить, какие параметры относятся к зашифрованным столбцам и, следовательно, должны быть зашифрованы. Для каждого параметра, который должен быть зашифрован, драйвер получает информацию об алгоритме шифрования и зашифрованное значение ключа шифрования столбца для столбца, к которому относится параметр, а также расположение соответствующего главного ключа столбца.
Затем драйвер обращается к хранилищу ключей, которое содержит главный ключ столбца, чтобы расшифровать зашифрованное значение ключа шифрования столбца, а затем использует ключ шифрования столбца с обычным текстом, чтобы зашифровать параметр. Получившийся ключ шифрования столбца с обычным текстом кэшируется с целью уменьшения количества циклов обмена данными с хранилищем ключей при последующем использовании того же ключа шифрования столбца. Драйвер подставляет вместо значений параметров, относящихся к зашифрованным столбцам, в виде обычного текста их зашифрованные значения и отправляет запрос на сервер для обработки.
Сервер вычисляет набор результатов, и для всех зашифрованных столбцов в результирующем наборе драйвер прикрепляет метаданные шифрования для столбца, включая сведения об алгоритме шифрования и соответствующих ключах. Драйвер сначала пытается найти ключ шифрования столбца с обычным текстом в локальном кэше и обращается к главному ключу столбца только в том случае, если не может найти ключ в кэше. Затем драйвер расшифровывает результаты и возвращает значения в виде обычного текста в приложение.
Клиентский драйвер взаимодействует с хранилищем ключа, которое содержит главный ключ столбца, используя поставщик хранилищ главных ключей столбцов. Этот поставщик представляет собой клиентский программный компонент, который инкапсулирует хранилище ключей, содержащее главный ключ столбца. Поставщики распространенных типов хранилищ ключей доступны в клиентских библиотеках драйверов Майкрософт или как изолированные файлы для скачивания. Кроме того, можно реализовать собственный поставщик. Функции Always Encrypted, включая встроенные поставщики хранилищ главных ключей столбцов, различаются по библиотеке драйверов и ее версии.
Дополнительные сведения о разработке приложений с помощью Always Encrypted с определенными клиентскими драйверами см. в разделе Разработка приложений с помощью Always Encrypted.
Remarks
Шифрование и расшифровка осуществляются с помощью драйвера клиента. Это означает, что некоторые действия, которые происходят только на стороне сервера, при использовании Always Encrypted работать не будут. Помимо прочего, к этим действиям относятся:
Ниже приведен пример инструкции UPDATE, которая пытается переместить данные из зашифрованного столбца в незашифрованный, не возвращая в клиент результирующий набор:
Если SSN — столбец с шифрованием Always Encrypted, инструкция «update», приведенная выше, не сработает и выдаст следующую ошибку:
Чтобы обновить столбец, сделайте следующее.
В этом сценарии при обратной отправке на сервер данные будут расшифрованы, так как целевой столбец имеет обычный тип «varchar» и не принимает зашифрованные данные.
Выбор детерминированного или случайного шифрования
Database Engine никогда не работает с данными в виде обычного текста, хранимыми в зашифрованных столбцах, но поддерживает определенные запросы, адресованные зашифрованным данным, в зависимости от типа шифрования для столбца. Постоянное шифрование поддерживает два типа шифрования: случайное и детерминированное.
Детерминированное шифрование всегда создает одно и то же зашифрованное значение для любого текстового значения. Использование детерминированного шифрования позволяет выполнять поиск точек, создавать соединения равенства, группировать и индексировать зашифрованные столбцы. Тем не менее в этом случае несанкционированные пользователи также могут угадать информацию о зашифрованных значениях, изучив закономерности в зашифрованном столбце, особенно при наличии небольшого набора возможных зашифрованных значений, таких как True и False или Север, Юг, Восток, Запад. При использовании детерминированного шифрования необходимо указать порядок сортировки binary2 в параметрах сортировки для символьных столбцов.
Случайное шифрование использует метод, который шифрует данные менее предсказуемым образом. Случайное шифрование более безопасно, но не позволяет выполнять поиск, группировку, индексирование и объединение по зашифрованным столбцам.
Детерминированное шифрование используется для столбцов, которые будут применяться в качестве параметров поиска или группирования. Например, ИНН. Используйте случайное шифрование для данных, например конфиденциальных комментариев о расследованиях, которые не сгруппированы с другими записями и не используются для соединения таблиц. Подробные сведения об алгоритмах шифрования Always Encrypted см. в разделе Шифрование Always Encrypted.
Настройка постоянного шифрования
Первоначальная настройка постоянного шифрования в базе данных подразумевает создание ключей постоянного шифрования и метаданных этих ключей, настройку свойств шифрования столбцов выбранной базы данных и (или) шифрование данных, которые, возможно, уже существуют в столбцах, которые требуется зашифровать. Обратите внимание, что некоторые из этих задач не поддерживаются в Transact-SQL и требуют использования клиентских средств. Поскольку ключи постоянного шифрования и защищенные конфиденциальные данные никогда не открываются серверу в виде обычного текста, Database Engine невозможно использовать для подготовки ключей и шифрования или расшифровки данных. Для выполнения этих задач можно использовать SQL Server Management Studio или PowerShell.
| Задача | SSMS | PowerShell | T-SQL |
|---|---|---|---|
| Подготовка главных ключей столбца, ключей шифрования столбцов и ключей шифрования зашифрованных столбцов с соответствующими главными ключами столбца. | Да | Да | нет |
| Создание ключа метаданных в базе данных. | Да | Да | Да |
| Создание новых таблиц с зашифрованными столбцами | Да | Да | Да |
| Шифрование существующих данных в выбранных столбцах базы данных | Да | Да | нет |
Always Encrypted с безопасными анклавами, представленными в SQL Server 2019 (15.x), поддерживает шифрование существующих данных с помощью Transact-SQL. Это также избавляет от необходимости перемещать данные за пределы базы данных для выполнения криптографических операций.
Убедитесь, что запуск инструментов подготовки ключей или шифрования данных осуществляется в безопасной среде, на компьютере, отличном от компьютера, на котором размещена ваша база данных. В противном случае возможна утечка конфиденциальных данных или ключей в серверную среду, что сведет преимущества использования постоянного шифрования к минимуму.
Дополнительные сведения о настройке постоянного шифрования см. в следующих разделах:
Приступая к работе с постоянным шифрованием
Видео, в котором демонстрируется использование мастера, см. на странице Начало работы с постоянным шифрованием с помощью SSMS.
Сведения о возможностях
Запросы могут выполнять сравнение на равенство по столбцам, зашифрованным с помощью детерминированного шифрования, но не другие операции (например, больше или меньше, сопоставление шаблонов с помощью оператора LIKE или арифметические операции).
Запросы для столбцов, зашифрованных с помощью случайного шифрования, не могут выполнять никаких операций. Индексирование столбцов, зашифрованных с помощью случайного шифрования, не поддерживается.
Always Encrypted с безопасными анклавами, представленными в SQL Server 2019 (15.x), устраняет описанное выше ограничение, включая сопоставление шаблонов, операторы сравнения и индексирование столбцов с использованием случайного шифрования.
У ключа шифрования столбца может быть до двух разных зашифрованных значений, каждое из которых зашифровано с помощью различных главных ключей столбца. Это позволяет менять главные ключи столбца.
Для детерминированного шифрования к столбцу необходимо применять один из параметров сортировки binary2.
После изменения определения для зашифрованного объекта выполнение процедуру sp_refresh_parameter_encryption для обновления метаданных постоянного шифрования.
Always Encrypted не поддерживается для столбцов с указанными ниже характеристиками. Например, если какое-либо из следующих условий применяется к столбцу, предложение ENCRYPTED WITH нельзя использовать в CREATE TABLE/ALTER TABLE для столбца:
Следующие предложения не могут использоваться для зашифрованных столбцов:
Следующие функции не работают для зашифрованных столбцов:
Требования к средствам
Разрешения базы данных
Существует четыре разрешения для постоянного шифрования:
ALTER ANY COLUMN MASTER KEY (Требуется для создания и удаления главного ключа столбца.)
ALTER ANY COLUMN ENCRYPTION KEY (Требуется для создания и удаления ключа шифрования столбца.)
VIEW ANY COLUMN MASTER KEY DEFINITION (Требуется для доступа к метаданным главных ключей столбцов и их чтения с целью управления ключами или отправки запросов в зашифрованные столбцы.)
VIEW ANY COLUMN ENCRYPTION KEY DEFINITION (Требуется для доступа к метаданным ключей шифрования столбцов и их чтения с целью управления ключами или отправки запросов в зашифрованные столбцы.)
В следующей таблице приводятся обобщенные сведения о разрешениях, необходимых для выполнения стандартных действий.
| Сценарий | ALTER ANY COLUMN MASTER KEY | ALTER ANY COLUMN ENCRYPTION KEY | VIEW ANY COLUMN MASTER KEY DEFINITION | VIEW ANY COLUMN ENCRYPTION KEY DEFINITION |
|---|---|---|---|---|
| Управление ключами (создание, изменение или просмотр метаданных ключа в базе данных) | X | X | X | X |
| Отправка запросов в зашифрованные столбцы | X | X |
Важные примечания.
Разрешения распространяются на действия, которые выполняются с использованием Transact-SQL, Среда Management Studio (диалоговые окна и мастер) или PowerShell.
Два разрешения VIEW требуются при выборе зашифрованных столбцов, даже если у пользователя нет разрешения на расшифровку столбцов.
Пример
Следующая операция Transact-SQL создает метаданные главного ключа столбца, метаданные ключа шифрования столбца и таблицу с зашифрованными столбцами. Сведения о создании ключей, на которые ссылаются метаданные, см. в следующих разделах.
