Шифрование и дешифрование базы данных Access. Шифрование базы данных. Шифрование баз данных средствами MS SQL Server

При шифровании базы данных ее файл сжимается и делается недоступным для чтения с помощью служебных программ или текстовых редакторов. Шифрование базы данных не ограничивает доступ пользователей к объектам. Дешифрование базы данных является операцией, обратной шифрованию.

Чтобы зашифровать или дешифровать базу данных, необходимо быть либо владельцем базы данных, либо, если база данных защищена, членом группы «Admins» с разрешением «монопольный доступ». Перед шифрованием базы данных рекомендуется сохранить ее с другим именем либо на другом диске или папке. В процессе шифрования Microsoft Access не заменяет исходную базу данных до успешного завершения шифрования. Необходимо иметь на диске достаточно места для исходной и зашифрованной версии базы данных.

    Запустите Microsoft Access без открытия базы данных. При работе с сетевой (общей) базой данных убедитесь, что все пользователи закрыли базу данных.

Важно! Нельзя зашифровать или дешифровать открытую базу данных.

    В меню Сервис выберите командуЗащита и подкомандуШифровать/дешифровать .

    Укажите имя базы данных, которую требуется зашифровать или дешифровать, и нажмите кнопку OK .

    Укажите имя, диск и папку для конечной базы данных и нажмите кнопку OK .

Если указаны те же имя, диск и папка, что и у исходной базы данных, а шифрование или дешифрование базы данных выполнено успешно, то исходный файл будет заменен на зашифрованный или дешифрованный. Если же операция приводит к ошибке, то исходный файл удален не будет.

Создание, присоединение и исправление файлов рабочих групп

В файле рабочей группы Microsoft Access хранятся сведения о членах рабочей группы, включая пароли пользователей. При открытии базы данных этот файл читается для определения пользователей, которым разрешен доступ к объектам базы данных, и разрешений, полученных пользователями на эти объекты.

Создание и присоединение файла рабочей группы

Файл рабочей группы содержит список пользователей, совместно использующих данные, также известный как рабочая группа. Пароли пользователей также запоминаются в файле рабочей группы. Для управления доступом к базе данных необходимо создать новый файл рабочей группы.

    Запустите Microsoft Access.

    В меню Сервис выберите командуЗащита , а затем командуАдминистратор рабочих групп .

    В диалоговом окне Администратор рабочих групп нажмите кнопкуСоздать .

    В диалоговом окне Сведения о владельце рабочей группы введите свое имя, название организации и любое сочетание букв и цифр длиной до 20 знаков в качестве кода рабочей группы (WID).

    Введите имя нового файла рабочей группы. По умолчанию файл рабочей группы сохраняется в папке языка. Чтобы сохранить его в другой папке, введите новый путь или нажмите кнопку Обзор , чтобы выбрать новый путь.

    Нажмите кнопку OK .

Новый файл рабочей группы будет использоваться при следующем запуске Microsoft Access. Любые создаваемые учетные записи пользователей и учетные записи групп, а также их пароли, сохраняются в новом файле рабочей группы. Чтобы присоединить к рабочей группе, определенной новым файлом рабочей группы, других пользователей, скопируйте этот файл в общую папку (если он не был сохранен на шаге 5 в общей папке); после этого каждый пользователь должен будет запустить «Администратор рабочих групп» и присоединиться к новому файлу рабочей группы.

Шифрование баз данных и соединений поддерживается с версии 2009. Данная статья написана по документации и функционалу InterBase XE3. Некоторых опций, указанных в статье, может не быть в предыдущих версиях InterBase - XE, 2009, или могут быть добавлены в последующих - XE7 (XE7, к сожалению, рекомендовать никак не могу, т.к. в любом апдейте этой версии есть баги, которые приводят к повреждениям БД при интенсивной работе).

О шифровании соединений в InterBase изложено . В этой статье описано только шифрование базы данных и/или столбцов таблиц.

Дальнейший текст - по мотивам незаконченного в блоге
Сразу предупреждаю, что шифрование баз - сложная штука, и если кто-то думает, что можно было бы все это сделать тяп-ляп, то он ошибается.

Обзор шагов шифрования

Для шифрования базы данных и/или столбцов таблиц требуется выполнить последовательно ряд действий. Эти действия, в корректном порядке, перечислены в следующей таблице:
Шаг Задача Кто выполняет
1 Включить EUA, задать пароль SYSDBA владелец БД
2 Создать пользователя SYSDSO (System Database Security Owner) владелец БД
3 Создать System Encryption Password (SEP, системный пароль) SYSDSO
4 Создать ключи для шифрования БД и/или столбцов SYSDSO
5 Дать права пользователю или владельцу БД на использование ключей шифрования SYSDSO
6 Зашифровать БД и/или столбцы владелец БД или пользователь
7 Дать права на чтение зашифрованных данных некоторым пользователям владелец БД или пользователь
Полностью и детально шифрование БД описано в документации на InterBase XE3, в Data Definition Guide, Глава 13, Encrypting Your Data . В этой статье убраны мелкие детали (иначе пришлось бы растянуть это на много страниц). Тем не менее, вы можете выполнять приводимое здесь по шагам над вашей тестовой базой данных, и получить шифрование БД в том или ином виде.

Для возврата БД к исходному состоянию нужно выполнить операции в обратном порядке. Поэтому, все выполненные действия по шифрованию эксплуатируемой БД должны быть обязательно записаны.

1. Включение EUA

Первым требованием перед включением шифрования БД является включение в базе Embedded User Authentification . Эта штука появилась еще в InterBase 7.5 в 2005 году, и позволяет проводить аутентификацию пользователей и SYSDBA через саму БД, а не через общий admin.ib для всех баз на сервере.

EUA является первым средством, которое позволяет защититься от ситуации "украли файл с базой", т. к. если пароль SYSDBA в базе будет не masterkey, то его придется или подбирать, или как-то хакать hex-editor-ом (не пробовал). Но, как минимум, это уже хоть какая-то защита от "чайников".

Итак, берем какую-нибудь тестовую базу, которую не жалко в случае ошибки, и в случае чего можно удалить или пересоздать. База должна быть создана не менее чем в InterBase 2009 (где впервые было сделано шифрование БД), но эту версию уже можно считать устаревшей, поэтому я настаиваю на XE или XE3 (для экспериментов можно взять Developer Edition, если ее у вас ее еще нет - выбираем InterBase XE3 (11.0.3.655) 32-bit Developer Edition - Windows, English или InterBase XE3 (11.0.3.655) 64-bit Developer Edition - Windows, English). Иначе часть описываемых функций у вас может не заработать. Шифрование включается для каждой БД отдельно.

Внимание! Теоретически, все выполняемые ниже действия можно сделать "мышекликаньем" в IBConsole. Однако, как показывает практика, IBConsole глючит, поэтому операции, относящиеся к шифрованию БД, в IBConsole выполнять опасно. Отчасти поэтому, а в основном для того, чтобы вы лучше поняли смысл действий, все команды приведены в виде SQL. Выполнять их можно в любом инструменте - isql, IBExpert, SQL Manager, и т. д.

Логинимся под SYSDBA, включаем в базе EUA

ALTER DATABASE ADD ADMIN OPTION


Меняем пароль SYSDBA

ALTER USER SYSDBA SET PASSWORD "sss"


Понятно, что пароль sss и подобные тут просто для того, чтобы не замучил склероз. Предлагаю по мере выполнения действий записывать их в "блокнотик" с цитатами отсюда, или собственными комментариями - получилось, не получилось, и т. п.

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

Разлогиниваемся, проверяем - пароль masterkey больше не работает, используем sss - ок, подключились.

Примечание. С этого момента "вернуть" пароль masterkey подменой admin.ib или переносом базы на другой сервер не получится. То есть, получится, но только отключением EUA, для чего нужно будет знать новый пароль SYSDBA.

2. Создание пользователя SYSDSO

Cоздаем пользователя SYSDSO - SYStem Database Security Owner (его может создать только SYSDBA или владелец БД), который является обязательным для включения шифрования

CREATE USER SYSDSO SET PASSWORD "ooo"


Этот пользователь является "ключником", и не может выполнять никакие другие функции, кроме:
  1. создания системного пароля шифрования (System Encryption Password или SEP)
  2. создания ключей шифрования
  3. выдачи прав другим пользователям на использование созданных ключей шифрования для шифрования базы данных или столбцов таблиц
Больше SYSDSO делать ничего не умеет и не должен.

3. Создание System Encryption Password

Разлогиниваемся, если мы все еще подключены как SYSDBA, логинимся как SYSDSO.

Создаем SEP для базы

ALTER DATABASE SET SYSTEM ENCRYPTION PASSWORD "aaa"

Внимание! При генерации System Encryption Password (SEP) используется информация, специфичная для текущего компьютера. Поэтому на этой машине далее при доступе к БД указывать SEP не требуется (хотя такое требование можно включить), а при переносе БД на другой компьютер никто без указания пароля SEP к базе подключиться не сможет . Можно указывать пароль SEP в параметрах коннекта (isc_dbp_system_encrypt_password), но это доступно только компонентам прямого доступа (типа IBX, FIBPlus, FireDAC, ...). Либо, можно указать SEP в переменных среды ОС (переменная ISC_SYSTEM_ENCRYPT_PASSWORD). Поэтому, если администратор переносит БД на другой сервер, то лучше сделать так - SYSDSO должен залогиниться к базе на новом сервере, используя свой пароль и старый SEP, и создать новый SEP. Новый SEP будет привязан уже к этому компьютеру, и остальным пользователям указывать его при коннекте не потребуется.
Для мобильных платформ с использованием IBLite, где подобные операции проводить как минимум неудобно, нужно явно указывать SEP при подключении к локальной БД.

Если есть желание, чтобы даже сейчас, на этом компьютере, пользователям требовалось указывать при коннекте пароль SEP (если ваше приложение позволяет указывать этот пароль помимо обычного пароля. Если нет, они обломаются, и так лучше не делать), то к данной команде можно добавить в конце опцию EXTERNAL .

Пример параметров для IBX.IBDatabase (или других компонент прямого доступа) с нашими паролями

user_name=SYSDBA
password=sss
lc_ctype=WIN1251


Для баз с SEP, требующим явного ввода, или для баз, перенесенных с конкретного компьютера, дополнительно прописывается (или задается динамически, или вообще запрашивается вместе с логином пользователя, как угодно)

system_encrypt_password=aaa


Пример для FireDAC - TFDConnection.Params

Protocol=TCPIP
Server=myserver
Database=c:\data\ibxes.ib
User_Name=SYSDBA
Password=sss
SEPassword=aaa
DriverID=IB

Внимание! При выборе других (кроме упомянутых FireDAC и IBX) компонент доступа к InterBase/IBLite при использовании шифрования необходимо проверить, поддерживают ли они передачу параметра для пароля SEP. Если нет, часть функций, описанных в статье, вы использовать не сможете. Например, dbExpress такого параметра не имеет, а значит как минимум в отношении зашифрованных баз данных на мобильных платформах его использовать нельзя.

SEP может иметь длину до 255 символов.

Убрать SEP (сделать это может только SYSDSO) можно командой

ALTER DATABASE SET NO SYSTEM ENCRYPTION PASSWORD

4. Создание ключей для шифрования БД и/или столбцов

Дальнейшие действия возможны в двух "опциях". InterBase поддерживает два алгоритма шифрования. DES и AES. DES можно использовать по умолчанию, в том числе в редакциях Trial и Developer, а вот AES можно включить только в полной (купленной) редакции. Впрочем, в использовании DES или AES нет никакой разницы, кроме, разумеется, факта, что AES является более сильным алгоритмом, и пришел на смену DES (для вскрытия которого несколько лет назад были даже созданы специализированные микросхемы). У DES длина ключа 56 байт, у AES - 128-256 байт.

Тем не менее, для проверки будет достаточно DES. Напомню, что шифровать можно как базу целиком, так и отдельные столбцы, поэтому я на всякий случай создам 3 разных ключа шифрования - один буду использовать для базы, и два для столбцов. Физически эти ключи не отличаются. Логинимся под SYSDSO, выполняем команды

CREATE ENCRYPTION db_des for DES
CREATE ENCRYPTION kname_des for DES
CREATE ENCRYPTION sname_des for DES


Все созданные ключи хранятся в таблице RDB$ENCRYPTIONS. Вообще команда CREATE ENCRYPTION сложнее:

create encryption key-name
]


AES или DES - тип ключа

Length - можно использовать только для AES, указывая длину ключа 128, 192 или 256 бит. 128 по умолчанию для AES.

Password - только для ключей, которыми шифруют столбцы, или используют для backup/restore. Можно использовать для дополнительной аутентификации при расшифровке зашифрованных столбцов. Для доступа к такому столбцу нужно или иметь право пользоваться ключом, с помощью которого зашифрован столбец, или знать пароль ключа и перед чтением зашифрованных данных выдать команду

set password "password" for column table.column_name


Init-vector - random включает Cipher Block Changing , при которой для одинаковых значений генерируется разный зашифрованный текст. При null для этого используется Electronic Codebook (в DataDef.pdf на странице 214 это указано как Electronic Cookbook). Null по умолчанию.

Pad - при random padding одинаковые значения могут давать разный результат шифрования. Null по умолчанию.

Description - комментарий к этому ключу - для чего предназначен и т. п.

Внимание! Включение init-vector random или pad random делают невозможным создание индекса по зашифрованному столбцу, при попытке проиндексировать такой столбец сервер выдаст ошибку. Нужно отметить, что и без init-vector и pad с поиском по индексированным зашифрованным столбцам не все хорошо, об этом будет дальше.

Чтобы удалить ключ шифрованиия, нужно выполнить команду

DROP ENCRYPTION имя_ключа


Если указано restrict, то ключ не удалится, если с его помощью уже зашифрованы данные. Если указано cascade, то вместе с удалением ключа будут дешифрованы все столбцы, которые были им зашифрованы.

Выполнять создание и удаление ключей может только SYSDSO.

5. Выдача прав на использование ключей шифрования

Чтобы пользователи могли зашифровать базу или столбцы, SYSDSO должен дать им гранты на использование ключей. Я даю гранты SYSDBA (но можно и кому-то еще):

GRANT ENCRYPT ON ENCRYPTION db_des to SYSDBA;
GRANT ENCRYPT ON ENCRYPTION kname_des to SYSDBA;
GRANT ENCRYPT ON ENCRYPTION sname_des to SYSDBA;


В этом месте я рекомендую сделать бэкап базы, а также отсоединиться от нее (и на всякий случай остановить сервис InterBase) и сделать копию файла. Далее мы будем шифровать базу и столбцы и сравнивать результаты.

Отобрать выданное право на использование ключа можно командой

REVOKE ENCRYPT ON ENCRYPTION FROM SYSDBA


Выполнять эти команды может только SYSDSO.

Тестовая база данных

Чтобы экспериментировать с шифрованием столбцов и базы, нужно чтобы в базе были какие то данные. В качестве готовых я в пустую базу с размером страницы 8192 байт залил данные KLADR - таблицы kladr и street, 190728 и 812609 записей, 17.5 и 98.5 мегабайт соответственно.

ALTER TABLE KLADR ADD CONSTRAINT PK_KLADR PRIMARY KEY (CODE);
CREATE INDEX BY_K_NAME ON KLADR (NAME);
ALTER TABLE STREET ADD CONSTRAINT PK_STREET PRIMARY KEY (CODE);
CREATE INDEX BY_S_NAME ON STREET (NAME);


Незашифрованная БД получилась 136мб (размер страницы 8192 байт).
  1. IBXES.IB - подготовленная к шифрованию база, незашифрованная
  2. IBXESD.IB - зашифрованная БД
  3. IBXESC.IB - база, в которой зашифрованы только строковые столбцы
  4. IBXESDC.IB - зашифрованная БД с зашифрованными столбцами
Исходно, конечно, файлы 2-4 являются эквивалентом ibxes.ib, но затем к ним будет применено то или иное шифрование, и можно будет оценить производительность и особенности каждого варианта.

Тестовый компьютер

Поскольку далее будут приводиться замеры времени выполнения определенных операций, приведу характеристики компьютера, на котором все это делалось, чтобы было с чем сравнить:
  • Процессор: AMD Phenom II X6 1075T
  • Материнская плата: Gigabyte GA-970A-UD3
  • Память: 16Gb, DDR3
  • Видеокарта: GeForce GTX 760
  • Операционная система: Windows 7 Ultimate 64 bit
  • Диск с базой: RAID 1, 2x Seagate ST2000DM001-1CH164 (2Tb, SATA 3).
  • RAID организован чипсетом матплаты, включен кэш Read Ahead и Write Back, для дисков включен NCQ и кэш записи.

6.1 Шифрование базы

Для шифрования всей базы данных выполняем

ALTER DATABASE ENCRYPT DB_DES

То есть, шифруем ее ключом db_des.

В результате выполнения операции


Prepare time = 0ms
Execute time = 10s 265ms
Current memory = 69 980 400
Max memory = 72 140 480
Memory buffers = 8 192
Reads from disk to cache = 16 992
Writes from cache to disk = 10 992
Fetches from cache = 17 143


Шифруются только страницы данных. Не шифруются - Header Page, Log page, Page Inventory Pages, Pointer Pages, Transaction Inventory Pages, Index root Pages, Generator Pages. Размер базы данных после шифрования не изменился.

Определить, зашифрована база или нет, можно вызовом

gstat -h ibxes.ib

При этом строка Attributes будет содержать флаг encrypted (если не зашифрована - этот флаг отсутствует). Для баз, где зашифрованы только столбцы, такая информация не выводится.

Чтобы дешифровать базу (привести в исходное состояние) нужно выполнить

ALTER DATABASE DECRYPT

6.2 Шифрование столбцов

Необходимо для случаев, когда данные в некоторых столбцах должны быть защищены от несанкционированного доступа. Например, если в таблице сотрудников есть столбец "зарплата", то понятно, что одним пользователям можно видеть данные в этом столбце, а другим - нельзя. Решить этот вопрос можно шифрованием столбца. Причем, если пользователю не разрешено видеть данные столбца, то может быть два варианта - при попытке просмотра либо будет выдано сообщение об ошибке о нехватке прав, либо будет показано некое "умолчательное" значение вместо реальных данных.

Внимание! В документации по InterBase слово decrypt используется в двух смыслах - как для операции, противоположной encrypt, так и для чтения зашифрованных данных. Для исключения путаницы далее я использую следующие слова: дешифрование - процесс, обратный шифрованию; расшифровка - процесс чтения зашифрованных данных.

Шифруем столбец STREET.NAME

ALTER TABLE STREET ALTER NAME ENCRYPT SNAME_DES


IBExpert в Performance Info может выдать такое:

1625218 record(s) was(were) updated in STREET
1625218 record(s) was(were) deleted from STREET
1625218 record(s) was(were) inserted into STREET

А может и не выдать. Причины такого поведения не очень понятны. Кроме того, в таблице STREET на самом деле 812609 записей, т. е. в 2 раза меньше, чем в данном выводе. Один раз вместо 1625218 вышло 2437827, что в 3 раза больше.

Сама операция выполняется мгновенно, потому что шифрование (или дешифрование) данных таблицы происходит по commit. То есть, при выполнении оператора вы увидите разве что

Performance info ------
Prepare time = 0ms
Execute time = 16ms
Current memory = 70 035 744
Max memory = 72 140 480
Memory buffers = 8 192
Reads from disk to cache = 0
Writes from cache to disk = 0


Причем, если это делается сразу после подключения, то commit может занять не более секунды. Возможно, потому, что вся база данных помещается в память. Однако, если выполнить дешифрование столбца, а потом опять повторить шифрование, то уже и дешифрование и шифрование займут существенное время. Например, дешифрование+коммит выполнялось 3 минуты, а последующее шифрование+коммит - 4 минуты. Причем, если такие операции выполняются несколько раз, время выполнения может дойти до 20 минут. Это связано с тем, что в отличие от шифрования страниц целиком шифруются только данные конкретного столбца, а делается это "перевставкой" данных. В итоге таблица начинает "пухнуть", и вместо 98мб получается 104мб, и так далее. Конечно, после этого срабатывает фоновая сборка мусора, и объем таблицы возвращается к прежнему.

Шифрование и дешифрование столбца, поскольку являются операциями alter table, увеличивают счетчик метаданных таблицы (счетчик форматов).

Как уже было сказано выше, если в базе данных зашифрованы только столбцы, а сама база данных не зашифрована, то в выводе gstat -h это никак не отражается. Увидеть признак "зашифрованности" столбца можно только в столбце RDB$ENCRYPTION_ID таблицы RDB$RELATION_FIELDS. В нем хранится код (порядковый номер) ключа шифрования из таблицы RDB$ENCRYPTIONS. Незашифрованные столбцы в этом поле содержат NULL.

Что интересно, для незашифрованного столбца можно выполнить дешифрование, и это займет упомянутое выше время. Вероятно, сервер некорректно обрабатывает null в rdb$encryption_id. К счастью, данные при таком псевдо-дешифровании не портятся.

Для зашифрованных столбцов функции MIN, MAX, BETWEEN и ORDER BY не смогут использовать индекс, поскольку в ключи индекса будут построены по зашифрованным данным (см. дальше).

Для возврата значений столбца в исходное, незашифрованное состояние, нужно выполнить

ALTER TABLE STREET ALTER NAME DECRYPT

Значение по умолчанию при расшифровке

После шифрования столбца, если у пользователя нет прав на расшифровку, он получит сообщение об ошибке при попытке прочитать зашифрованный столбец.

Для того, чтобы упростить работу с БД, для зашифрованного столбца возможно задать значение по умолчанию, которое будет выдаваться при несанкционированном чтении такого столбца. Это делается командой

ALTER TABLE STREET ALTER COLUMN NAME DECRYPT DEFAULT ""


В данном случае для строкового столбца NAME при отсутствии прав будет выдаваться пустая строка. Для других типов данных указываются соответствующие "пустые" значения - 0, "-", "secured", и так далее.

Если столбец дешифруется, то DECRYPT DEFAULT автоматически удаляется.

Проблема с поиском по индексу

В базе в самом начале был создан индекс BY_S_NAME по столбцу STREET.NAME.

Поиск без этого индекса, или по незашифрованному столбцу, проблем не имеет. Например, запрос

выдаст 55 (столько записей попадают под условие выборки).

Если столбец зашифровать, то запрос выдаст то же число 55. Однако, если начать поиск с одной буквы К до полного Краснооктябрьская, то мы получим такие значения

1 0 0 0 0 0 0 61 0 0 0 0 0 0 0 55 55

То есть, совершенно невразумительные результаты. С одной стороны, прослеживается некая "кратность 8", с другой стороны, непонятно, почему поиск по 1 символу выдал 1 (а не 76732), а по 17ти - выдал не 0, а то же, что и по 16ти.

Поэтому, индексы по зашифрованным строковым столбцам можно считать бесполезными.

Примечание. На других типах данных указанная проблема не проверялась.

6.3 Шифрование и базы, и столбцов

В этом случае выполняем действия пунктов 6.1 и 6.2 (или наоборот). В результате база будет зашифрована одним ключом, столбцы другими ключами. Здесь никаких особенностей, кроме указанных выше, нет.

7. Выдача прав на чтение зашифрованных столбцов

Для того, чтобы пользователи могли читать зашифрованный столбец, необходимо им дать права на расшифровку. Создадим тестового пользователя:

CREATE USER TEST SET PASSWORD "test"


Поскольку у нас в базе включено EUA, пользователь попадет не в "серверную" базу admin.ib, а будет храниться именно в нашей базе. Как минимум, это дает преимущество в том, что пользователей можно "включать" и "выключать", а не удалять их, как это делается в случае общей базы пользователей admin.ib. Разумеется, созданный пользователь ни к какой другой базе данных подключиться не сможет, т. к. на уровне "сервера" он не существует.

Дадим пользователю обычные права на чтение таблицы

GRANT SELECT ON STREET TO TEST


Проверим подключение с таким пользователем, и возможность чтения таблицы.

До тех пор, пока мы не будем выбирать столбец NAME, все будет хорошо. Однако, если мы напишем

select * from street

Или при явном перечислении выбираемых столбцов укажем NAME, то может быть два варианта:

  1. получим сообщение

no permission for decrypt access to column NAME by user TEST
если для столбца не было задано DECRYPT DEFAULT

  1. получим пустую строку вместо значений NAME, если для NAME было задано DECRYPT DEFAULT ""
Для того, чтобы дать пользователю видеть зашифрованные данные, нужно выполнить

GRANT DECRYPT (NAME) ON STREET TO TEST


Точно таким же образом права выдаются и ролям, или "общему" пользователю PUBLIC. Или можно дать право расшифровки для VIEW, а уже на VIEW дать пользователям право чтения, без всяких прав на расшифровку.

Отобрать права можно командой

REVOKE DECRYPT (NAME) ON STREET FROM TEST

Производительность

Разумеется, шифрование не дается бесплатно, и потребляет больше процессорных ресурсов. Для проверки на всех четырех типах БД выполнялся один и тот же запрос

select count(*) from street s


Для исключения влияния диска запрос выполнялся повторно 3-4 раза. Таким образом, вся база попадала как минимум в кэш операционной системы.

Результат получился примерно таким:

Здесь слева - время выполнения запроса в секундах. Надо сказать, что на чуть более старом процессоре (и другом железе) отличие получилось более существенным, хотя картина повторилась, например, если нешифрованную базу взять за 1, то зашифрованная была медленнее в 2.2 раз, столбец в 2 раза, и база+столбец - в 3.7 раз. На текущем компьтере максимальная разница не превысила 1.5 раз.

Понятно, что работа с зашифроваными данными или страницами замедляет работу, так что тут лучше использовать хороший процессор. Однако, если предполагается использовать шифрованную базу в однопользовательском режиме на офисных компьютерах, то стоит ожидать замедления, возможно даже четырехкратного.

Впрочем, приведенные данные не являются полноценным тестом, потому что база в 136 мегабайт это мелочь, и как видите, даже чтобы получить хоть какие-то заметные отличия в скорости запросов, пришлось запросом перебирать почти миллион записей.

Backup

Если в базе есть SYSDSO, то бэкапить нужно только с опцией -encrypt и -sep password. Иначе будет выдано сообщение

gbak: ERROR: -encrypt and -sep switches required to back up encryptions


Но если вы попробуете для -encrypt указать любой из уже нами созданных ключей, например, DB_DES, то будет выдана ошибка

gbak: ERROR: encryption DB_DES is not password-protected


То есть, для бэкапа даже еще не зашифрованной базы требуется отдельный ключ с паролем. Поэтому его нужно создать (не забудьте, что ключи создает и дает на них права пользователь SYSDSO)

CREATE ENCRYPTION dbackup for DES password "bbb"

И затем дать право использовать этот ключ тому, кто будет делать бэкап-рестор

GRANT ENCRYPT ON ENCRYPTION dbackup to SYSDBA;


Соответственно, при бэкапе в командной строке указывается, каким ключом шифруется бэкап

Encrypt key_name

А при ресторе указывается пароль для этого ключа

Decrypt key_password


Также, шифрованные базы бэкапятся и ресторятся только через Servcies API .

Таким образом, правильная команда

gbak -b n:\db\ibxe.ib n:\db\ibxe.ibk -user SYSDBA -pass sss -sep ""aaa"" -encrypt dbackup -se service_mgr -v

Обратите внимание на пароль для -sep - он указан в одинарных и снаружи еще и в двойных кавычках.

Restore

Поскольку создать базу на сервере может только SYSDBA/masterkey из admin.ib, а в базе у нас включено EUA, нужно указывать оба набора пользователь/пароль - серверный и для конкретной БД. Кроме того, обязательно использование Services API (опция -se), пароля -sep, и пароля ключа шифрования бэкапа

gbak -с n:\db\ibxe.ibk n:\db\ibxe.ib -user SYSDBA -pass masterkey -eua_u SYSDBA -eua_p sss -sep ""aaa"" -decrypt bbb -se service_mgr -v

Внимание! Каким-то образом по мере экспериментов у меня получилось сделать restore, только в самом конце вылезла ошибка про логин и пароль, а в базе не было ни EUA, ни пользователя SYSDSO, и так далее. Скорее всего, какой-то глюк.

Дополнения

  • Для получения статистики БД (gstat -r ... или через Services API) даже на этом же компьютере почему-то требуется указание System Encryption Password. Для этого gstat имеет дополнительную опцию -sep
  • Как выяснилось, SYSDBA не может сделать ничего "от имени" SYSDSO - попытки создать ключи, удалить ключи, выдать им гранты или напрямую редактировать системные таблицы в этом отношении будут выдавать ошибки типа

data security owner privilege required to encrypt or decrypt.
data security officer privilege required to modify encryption password
action cancelled by trigger (2) to preserve data integrity.
no permission for delete/write access to table RDB$ENCRYPTIONS by user SYSDBA

и т. д.
Однако, SYSDBA может выполнить единственную негативную операцию в отношении SYSDSO - это DROP USER SYSDSO. Как минимум, с целью создать этого пользователя заново с известным SYSDBA паролем, и далее манипулировать ключами "от имени SYSDSO.
Предполагается, что это баг .

  • Если остались непонятные моменты - читайте Data Definition Guide, Глава 13, Encrypting Your Data . Это файл datadef.pdf в каталоге установки InterBase. Документация поставляется во всех дистрибутивах InterBase - Developer Edition, Trial, Server, и так далее. В крайнем случае, datadef.pdf (и другие книги, при необходимости), можно скачать .
  • Если у вас есть вопросы по статье или предложения по тестированию зашифрованных баз, присылайте их на с темой "шифрование в InterBase".

Благодарности

Гаджимурадов Рустам - за мысль о деструктиве SYSDBA в отношении SYSDSO.
Симонов Денис - за предположение, что SYSDBA может манипулировать ключами SYSDSO.
hvlad и WildSery - за указание на ошибки и неточности.

Базит Фарук

Сообщения о потерях и несанкционированном доступе к конфиденциальным данным появляются все чаще, а значит безопасность баз данных - весьма актуальная проблема для многих компаний. Организации, в чьих базах данных хранится конфиденциальная информация, должны соблюдать требования многочисленных законодательных актов, в том числе Грэмма-Лича-Блайли (GLBA), директивы защиты данных ЕС (EUDPD), акта о преемственности и подотчетности медицинского страхования (HIPAA), стандарта безопасности данных индустрии платежных карт (PCI DSS) и закона Сарбейнса-Оксли (SOX). Эти законы требуют шифрования конфиденциальной информации на уровне базы данных и операционной системы. , как и другие распространенные коммерческие системы управления базами данных, располагает множеством вариантов шифрования, в том числе на уровне ячеек, базы данных и файлов через Windows, а также на транспортном уровне. Эти варианты шифрования обеспечивают безопасность информации на уровне базы данных и операционной системы. Кроме того, они снижают вероятность несанкционированного раскрытия конфиденциальных сведений, даже если поражены инфраструктура или база данных . После описания модели шифрования я рассмотрю возможности шифрования, реализованные в , а также способы шифрования конфиденциальной информации, сохраненной в базах данных .

Модель шифрования SQL Server

Теперь мы можем приступить к шифрованию данных. Для этого необходимо сначала открыть симметричный ключ, только что созданный с помощью команды OPEN SYMMETRIC KEY, за которой следует имя симметричного ключа. Затем вы указываете, что нужно расшифровать его с использованием заданного асимметричного ключа. Программный код выглядит следующим образом:

USE GO OPEN SYMMETRIC KEY MySymmetricKey DECRYPTION BY ASYMMETRIC KEY MyAsymmetricKey WITH PASSWORD = "StrongPa$$w0rd!" GO

После выполнения этого кода направьте запрос в представление sys.openkeys, чтобы убедиться, что ключ открыт:

USE GO SELECT * FROM .

Будут получены результаты, аналогичные показанным на рисунке 2. Наконец, необходимо ввести несколько номеров кредитных карт в таблицу CreditCardInformation, запустив код из листинга 2 . Затем направьте запрос к таблице CreditCardInformation:

USE GO SELECT * FROM .[ CreditCardInformation]

Как показано на рисунке 3, все данные в столбце CreditCardNumber представлены в двоичном формате. С помощью функции DECRYPTBYKEY можно просмотреть зашифрованные данные:

USE GO SELECT CONVERT((32), DECRYPTBYKEY(CreditCardNumber)) AS FROM . GO

Результаты показаны на рисунке 4.

Демонстрация 2. Во второй демонстрации данные шифруются с использованием асимметричного ключа, но на этот раз симметричный ключ шифруется сертификатом. Для этого выполните код из листинга 3 . Сначала создается сертификат с помощью инструкции CREATE CERTIFICATE. Затем создается симметричный ключ, шифруемый сертификатом. Наконец, открыв симметричный ключ, код вставляет три строки в таблицу CreditCardInformation.

Преимущества и недостатки шифрования на уровне ячеек

У шифрования на уровне ячеек есть свои достоинства и недостатки. Среди достоинств - более детальный уровень шифрования, что позволяет зашифровать единственную ячейку внутри таблицы. Кроме того, данные не расшифровываются, пока не придет время их использовать, то есть данные из загруженной в память страницы зашифрованы. Можно назначить ключ пользователям и защитить его паролем, чтобы предотвратить автоматическую расшифровку.

Среди недостатков шифрования на уровне ячеек - необходимость изменения схемы, так как все зашифрованные данные должны быть сохранены с использованием типа данных varbinary. Кроме того, снижается общая производительность базы данных из-за дополнительной обработки при шифровании и расшифровке данных. Требует времени и просмотр таблицы, поскольку индексы для таблицы зашифрованы и не могут быть использованы.

Прозрачное шифрование данных

В SQL Server 2008 появилась возможность зашифровать всю базу данных с использованием прозрачного шифрования. При таком шифровании можно защитить базы данных без изменения существующих приложений, структур баз данных или процессов. Это лучший вариант для выполнения требований нормативных актов и правил корпоративной безопасности, поскольку шифруется вся база данных на жестком диске.

Прозрачное шифрование данных шифрует базы данных в реальном времени, по мере внесения записей в файлы (*.mdf) базы данных и файлы (*.ldf) журнала транзакций. Записи также шифруются в реальном времени во время резервного копирования базы данных, а затем формируются моментальные снимки. Данные шифруются перед записью на диск и расшифровываются перед извлечением. Процесс полностью прозрачен для пользователя или приложения, поскольку выполняется на уровне SQL Server Service.

Листинг 1. Программный код для создания ключей для демонстрации 1

USE GO - Создание асимметричного ключа, зашифрованного - парольной фразой StrongPa$$w0rd! CREATE ASYMMETRIC KEY MyAsymmetricKey WITH ALGORITHM = RSA_2048 ENCRYPTION BY PASSWORD = "StrongPa$$w0rd!" GO - Создание симметричного ключа, зашифрованного - асимметричным ключом. CREATE SYMMETRIC KEY MySymmetricKey WITH ALGORITHM = AES_256 ENCRYPTION BY ASYMMETRIC KEY MyAsymmetricKey GO

Листинг 2. Программный код для заполнения таблицы CreditCardInformation

USE GO DECLARE @SymmetricKeyGUID AS SET @SymmetricKeyGUID = KEY_GUID("MySymmetricKey") IF (@SymmetricKeyGUID IS NOT NULL) BEGIN INSERT INTO . VALUES (01, ENCRYPTBYKEY(@SymmetricKeyGUID, N"9876-1234-8765-4321")) INSERT INTO . VALUES (02, ENCRYPTBYKEY(@SymmetricKeyGUID, N"9876-8765-8765-1234")) INSERT INTO . VALUES (03, ENCRYPTBYKEY(@SymmetricKeyGUID, N"9876-1234-1111-2222")) END TRUNCATE TABLE .

Листинг 3. Программный код для шифрования данных с использованием симметричного ключа,

зашифрованного сертификатом

USE GO - Создание сертификата. CREATE CERTIFICATE WITH SUBJECT = "Самозаверяющий сертификат для шифрования симметричного ключа." - Создание симметричного ключа, зашифрованного - сертификатом. CREATE SYMMETRIC KEY WITH ALGORITHM = AES_256 ENCRYPTION BY CERTIFICATE - Открытие симметричного ключа. OPEN SYMMETRIC KEY DECRYPTION BY CERTIFICATE - Усечение таблицы CreditCardInformation. TRUNCATE TABLE . - Вставка данных в таблицу. DECLARE @SymmetricKeyGUID AS SET @SymmetricKeyGUID = KEY_GUID("SymmetricKeyEncryptedWithCert") IF (@SymmetricKeyGUID IS NOT NULL) BEGIN INSERT INTO . VALUES (01, ENCRYPTBYKEY(@SymmetricKeyGUID, N"9876-1234-8765-4321")) INSERT INTO . VALUES (02, ENCRYPTBYKEY(@SymmetricKeyGUID, N"9876-8765-8765-1234")) INSERT INTO . VALUES (03, ENCRYPTBYKEY(@SymmetricKeyGUID, N"9876-1234-1111-2222")) END

Чтобы предотвратить несанкционированное использование базы данных Access, ее можно зашифровать с помощью пароля. После этого расшифровать базу данных и удалить пароль можно будет, только введя его. В этой статье описано, как зашифровать базу данных с помощью пароля, а также расшифровать ее и удалить из нее пароль.

В более ранних версиях Access можно создать учетные записи пользователей и паролей, используя функцию с именем безопасности на уровне пользователя. В этом разделе рассматривается безопасности на уровне пользователя, который не поддерживается при использовании формате ACCDB.

Зашифрованную базу данных, пароль от которой утерян, невозможно использовать. Если пароль неизвестен, его нельзя удалить.

В этой статье

Обзор

С помощью средства шифрования можно предотвратить чтение базы данных через другие средства и защитить ее паролем. При этом необходимо помнить указанные ниже правила.

    Новая функция шифрования действует только в отношении баз данных в формате ACCDB.

    Это средство использует более стойкий алгоритм шифрования, чем в предыдущих версиях Access.

    При шифровании баз данных, созданных в более ранних версиях Access (MDB-файлов), или применении к ним паролей используются соответствующие функции из Access 2003.

Шифрование базы данных с помощью пароля

В этом разделе описано, как создать пароль и применить к базе данных Access рабочего стола.

Шифрование базы данных

Шифрование разделенной базы данных

Чтобы зашифровать разделенную базу данных, эту процедуру нужно выполнить для ее интерфейсной и серверной части. При шифровании серверной базы данных изменяются связи с ее таблицами.

Открытие и расшифровка базы данных

Напоминание. Обязательно запомните пароль. Забытый пароль невозможно восстановить.

SSL/SSH protects data travelling from the client to the server: SSL/SSH does not protect persistent data stored in a database. SSL is an on-the-wire protocol.

Once an attacker gains access to your database directly (bypassing the webserver), stored sensitive data may be exposed or misused, unless the information is protected by the database itself. Encrypting the data is a good way to mitigate this threat, but very few databases offer this type of data encryption.

The easiest way to work around this problem is to first create your own encryption package, and then use it from within your PHP scripts. PHP can assist you in this with several extensions, such as Mcrypt and Mhash , covering a wide variety of encryption algorithms. The script encrypts the data before inserting it into the database, and decrypts it when retrieving. See the references for further examples of how encryption works.

Hashing

In the case of truly hidden data, if its raw representation is not needed (i.e. will not be displayed), hashing should be taken into consideration. The well-known example for hashing is storing the cryptographic hash of a password in a database, instead of the password itself.

// storing password hash
// $random_chars retrieved e.g. using /dev/random
$query = sprintf ("INSERT INTO users(name,pwd) VALUES("%s","%s");" ,
pg_escape_string ($username ),
pg_escape_string (crypt ($password , "$2a$07$" . $random_chars . "$" )));
$result = pg_query ($connection , $query );

// querying if user submitted the right password
$query = sprintf ("SELECT pwd FROM users WHERE name="%s";" ,
pg_escape_string ($username ));
$row = pg_fetch_assoc (pg_query ($connection , $query ));

if ($row && crypt ($password , $row [ "pwd" ]) == $row [ "pwd" ]) {
echo "Welcome, " . htmlspecialchars ($username ) . "!" ;
} else {
echo "Authentication failed for " . htmlspecialchars ($username ) . "." ;
}

?>

6 years ago

I would strongly recommend using SHA-2 or better the new SHA-3 hash algorithm. MD5 is practically unusable, since there are very well working rainbow tables around the whole web. Almost the same for SHA-1. Of course you should never do a hash without salting!

7 years ago

Using functions to obfuscate the hash generation does not increase security. This is security by obscurity. The algorithm used to hash the data needs to be secure by itself.

I would not suggest to use other data as salt. For example if you use the username, you won"t be able to change the values without rehashing the password.

I would use a dedicated salt value stored in the same database table.

Why? Because a lot of users use the same login credentials on different web services. And in case another service also uses the username as salt, the resulting hashed password might be the same!

Also an attacker may prepare a rainbow table with prehashed passwords using the username and other known data as salt. Using random data would easily prevent this with little programming effort.