Шифрування в базах даних SQL з можливістю пошуку

Ця стаття буде корисна інженерам, які працюють з базами даних SQL, і інженерам-криптографам. Searchable Encryption як раз знаходиться на стику баз даних і криптографії і вимагає знання обох предметів. Стаття висвітлює внутрішнє інженерне дослідження, яке проводилося в компанії Cossack Labs перед створенням пошукового модуля шифрування для одного з наших програмних продуктів, орієнтованого на комплексний захист SQL баз даних (Acra ).

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

Дослідження відображає нашу думку про поточний стан і перспективи Searchable Encryption в широкому контексті.

Введення

Швидке просування інтернет-технологій сприяло розвитку моделі «програмне забезпечення як сервіс» (software as a service) в корпоративному IT-секторі. Модель «база даних як сервіс» забезпечує користувачів можливістю створювати, зберігати, модифікувати і отримувати дані з віддаленого джерела, маючи доступ до інтернету. Оскільки все більша кількість даних переноситься на хмарні сервіси зберігання, користувачам потрібні гарантії безпеки їх даних від зовнішніх загроз витоку з цих сервісів. Крім цього, безпека повинна забезпечуватися і з боку самих сервісів, фактично мають повний доступ до серверів і, отже, до збережених даних. Ця ж проблема характерна і для складних розподілених додатків з комплексної микросервисной архітектурою. Для безпечного зберігання конфіденційних даних на недоверенном віддаленому сервісі дані повинні бути зашифровані.

Шифрування робить доступ до даних неможливим без знання криптографічних ключів для внутрішніх і зовнішніх атакуючих, але в той же час виключає можливість пошуку. Одне з тривіальних рішень цієї проблеми — завантажити всю базу даних, розшифрувати її локально і здійснити пошук вже за відкритими даними. Для більшості додатків такий підхід буде непрактичним у зв'язку зі значними обсягами даних. Інший метод — дозволити серверу розшифрувати дані, виконати запит і повернути користувачеві результат. В цьому випадку знижується рівень безпеки, так як дані захищені шифруванням, розкриваються сервера. Замість цього потрібна підтримка максимально можливої функціональності пошуку з мінімальною втратою конфіденційності даних. Це називається пошуковим шифруванням (searchable encryption— SE). На рис. 1 зображено абстрактний принцип роботи SE.

Рис. 1. Абстрактна схема пошукового шифрування

Схема пошукового шифрування дозволяє віддаленого сервісу зберігання даних виробляти пошук по зашифрованих даних без отримання інформації про відкритих даних. Деякі схеми реалізують це за допомогою спеціальних технік шифрування, що підтримують пошук, в той час як інші дозволяють клієнту згенерувати спеціальний індекс і зберегти його разом з зашифрованими даними на стороні сервера. Для пошуку клієнт генерує так званий trapdoor— предикат, що дозволяє серверу перевірити, чи включати зашифроване ключове слово в результати пошуку.

Останнім часом актуальність пошукового шифрування істотно зросла у зв'язку з прийняттям GDPR, який регламентує порядок захисту персональних даних і приватність громадян Європейського союзу. Іншим прикладом можуть бути вимоги міжнародних стандартів та нормативні вимоги багатьох держав по всьому світу про шифрування медичних даних (HIPAA) або даних банківського сектора (PCI DSS).

Перша SE-схема (її перше формальне науковий опис) була запропонована в 2000 р. Сьогодні академічною спільнотою запропоновано понад 50 описів схем з різноманітною функціональністю. Індустрія також пропонує велику кількість рішень, готових до використання (Bitglass, CipherCloud, Crypteron, IQrypt, Kryptnostic, google's Encrypted BigQuery, microsoft's SQL Server 2016, SQL Azure Database, PreVeil, SkyHigh, StealthMine та ін).

Добре відомо [link 1 , link 2 ], що проектування SE-схеми — це знаходження компромісу (tradeoff) між безпекою, функціональністю запитів, продуктивністю і зручністю використання (рис. 2). Коли в схемі поліпшується один з аспектів, зазвичай це призводить до погіршення одного або відразу декількох інших аспектів. Безпека зазвичай визначається інформацією про користувачів, яка стає відома атакуючому в процесі роботи схеми (leakage). Функціональність запитів визначається типами запитів, які підтримуються. Запити зазвичай виражаються за допомогою стандартних мов (наприклад, SQL).

Продуктивність характеризується структурами даних і механізмами індексування в базі даних поряд з обчислювальними і комунікаційними витратами.

Рис. 2. Баланс параметрів схеми пошукового шифрування

Поняття безпеки схеми пошукового шифрування

Для схем пошукового шифрування характерно власне поняття безпеки, оскільки всі найбільш потужні криптографічні атаки на такі системи будуються на основі експлуатації витоків (leakage inference attacks), яким піддається в більшій чи меншій мірі майже будь-яка практична SE-схема. У процесі роботи SE-схеми відбувається постійна взаємодія між клієнтом і сервером. При спостереженні і статистичному аналізі надходять від клієнта запитів і відповідей сервера противник може отримувати істотну кількість метаданих про зашифрованої інформації.

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

Інший спосіб отримання метаданих про зашифрованої інформації полягає в наступному. Припустимо, що атакуючий отримав знання про одному із запитів з пошукових виразом <Last_Name=Smith>. Припустимо також, що обидва різних запиту з пошуковими виразами <Fisrt_Name=John> і <Fisrt_Name=Matthew> повертають 1000 записів. Атакуючий може перевірити, скільки загальних записів у останніх (невідомих) запитів разом з першим (відомим). Наприклад, може бути 100 записів з ім'ям John Smith і тільки 10 записів з ім'ям Matthew Smith. Звіряючи такі перетину з раніше відомими запитами, противник може ідентифікувати Fisrt_Name. Такий підхід ітеративне ідентифікує запити і використовує їх як додаткові обмеження для подальшого визначення невідомих запитів.

Серед найбільш відомих і потужних атак такого роду можна виділити count-атаку, здатну відновлювати до 40% ключових слів, якщо їх розподіл невелика (до 5000), за умови, що атакуючому відомо 80% записів. Інший приклад — атака ієрархічного пошуку (hierarchical search attack). Вона є розширенням count-атаки і здатна при такому розподілі відновлювати до 80% ключових слів при витоку лише 40% записів, однак з допущенням, що противник активний і здатний включати свої записи в зашифровані дані користувача.

Існуючі схеми пошукового шифрування для баз даних SQL

Дослідження в області пошукового шифрування переважно концентруються на широкому контексті, коли користувальницькі дані структуровані у вигляді колекції документів, а пошук за ключовими словами (Dropbox і Google Drive). Однак на практиці організації часто використовують реляційну модель структурування даних з таблиць у відповідності з набором атрибутів. Синтаксис SQL добре визначений і дозволяє виконувати всі необхідні операції з даними (завантаження, модифікація, пошук і видалення). Отже, SE-схема повинна адаптуватися під конкретні SQL-запити, що використовуються в додатку. Крім цього, з практичної точки зору вкрай важливі такі параметри:

В табл. 1 наведена порівняльна характеристика різних SE-схем, що підтримують реляційну алгебру і, отже, адаптуються до баз даних SQL.

Табл. 1. Порівняння SE-схем

SE schemes Query expressiveness Security Performance overhead Easy integration with application (deploy) Open-source
CryptDB Equality, Boolean, Range, Update, Sum Low ~30% + +
Blind Seer Equality, Boolean, Range, Update Average ~20 — 300%
OSPIR-OXT Equality, Boolean, Range, Update Average ~1000%
SisoSPIR Equality, Range High ~500%
CipherSweet Equality High ~1000 — 1500% + +
.is_mobile .b-typo table tr:first-child td{font-size:10px;min-width:50px;vertical-align:middle;text-align:center}

Примітка. Дані для СryptDB, Blind Seer, OSPIR-OXT і SisoSPIR взяті з оригінальних робіт, що описують ці системи. Дані для CipherSweet отримані на підставі власного експериментального аналізу і можуть носити суб'єктивний характер.

CryptDB підтримує максимальну функціональність сучасних систем управління базами даних SQL з втратою продуктивності до 30%. Автори Blind Seer повідомляють, що їх падіння продуктивності коливається в межах 20-300% для більшості запитів. Автори OSPIR-OXT повідомляють, що в деяких випадках їх система навіть перевершує MySQL 5.5 з «холодним» кешем та на 1 порядок (1000%) повільніше, ніж MySQL з «теплим» кешем. Падіння продуктивності в SisoSPIR становить близько 500% на деяких видах запитів (equality і range).

У той же час, наданий системами рівень безпеки різний. При використанні атрибута в запиті CryptDB розкриває статистику всіх значень цього атрибута в таблиці. Blind Seer і OSPIR-OXT також розкривають сервера метадані про зашифрованої інформації, що повертається в результаті запиту. Тому ці системи варто використовувати у випадку рідкісного звернення до даних.

SisoSPIR забезпечує високий рівень захисту навіть у разі регулярних запитів (що є однією з вимог production-ready-систем) за рахунок введення додаткового інфраструктурного компонента — helper-сервера. При цьому SisoSPIR вимагає, щоб сервер, на якому зберігаються дані, не мав можливості «змовитися» (collude) з helper-сервером.

CipherSweet підтримує найменшу функціональність запитів (equality) і має відносно низьку продуктивність, однак надає високий рівень безпеки за рахунок простого і зрозумілого криптографічного дизайну. Слід зазначити, що CipherSweet (на відміну від систем, запропонованих академічними дослідниками) використовує техніку сліпого індексування (blind indexing technique), яка зародилася в інженерному співтоваристві і враховує багато практичні проблеми. Цей факт схилив нашу інженерну команду до вибору CipherSweet як прототипу для нашого програмного продукту.

Принцип роботи CipherSweet

Ідея техніки сліпого індексування, що використовується в CipherSweet, досить проста. Розглянемо просту SQL-таблицю з двома атрибутами Field_Aі Field_B, що містить три записи (табл. 2).

Табл. 2. Таблиця в базі даних SQL

Records Field_A Field_B
record_0 data_1 data_2
record_1 data_1 data_3
record_2 data_4 data_5

Для внесення нульового рядка в таку таблицю можна використовувати такий INSERT-запит (псевдо-SQL):

INSERT INTO table VALUES (data_1, data_2)

Для пошуку записів за атрибутом Field_Aможна використовувати такий SELECT-запит:

SELECT * FROM table WHERE Field_A = data_1

Результатом такого запиту буде таблиця, що містить два записи: record_0 і record_1.

При зашифровании даних сервер втрачає можливість проводити порівняння Field_A = data_1. Модифікуємо вихідну таблицю додаванням атрибута Field_A_index, в якому будуть міститися метадані про даних, позначених атрибутом Field_A(табл. 3). Тепер можна зашифрувати дані, використовуючи криптографічно стійкого (CPA secure) блочний шифр (наприклад, AES-256-GCM) по атрибуту Field_A, а для того, щоб працювало порівняння, потрібно в індекс записати результат застосування до даних криптографічно стійкою (PRF) псевдовипадковою функції (наприклад, PBKDF2 або Argon2). Позначимо операцію шифрування з допомогою функцій Enc/Dec (зашифрування і розшифрування відповідно) і операцію обчислення псевдовипадковою функції PRF. Табл. 4 демонструє порядок зберігання даних на сервері.

Табл. 3. Модифікація вихідної таблиці для CipherSweet

Records Field_A_index Field_A Field_B
record_0 index_1 data_1 data_2
record_1 index_1 data_1 data_3
record_2 index_4 data_4 data_5

Табл. 4. Подання зашифрованих даних на сервері недоверенном

Records Field_A_index Field_A Field_B
record_0 PRF(data_1) Enc(data_1) data_2
record_1 PRF(data_1) Enc(data_1) data_3
record_2 PRF(data_4) Enc(data_4) data_5

Для реалізації описаного принципу потрібно:

INSERT-запит для внесення record_0, складається з даних (data_1 і data_2), в таблицю перетворюється в таку форму:

INSERT INTO table VALUES (index_1, encrypted_data_1, data_2)

де index_1=PRF(data_1), encrypted_data_1=Enc(data_1).

SELECT-запит для вибірки по атрибуту Field_Aперетворюється в таку форму:

SELECT * FROM table WHERE Field_A_index=index_1

де index_1 = PRF (data_1). Після отримання результату запиту додаток може скористатися функцією Dec і розшифрувати дані по атрибуту Field_Aіз записів record_0 і record_1.

Зазначимо, що криптографічні ключі опущені в описі для спрощення. Мається на увазі, що шифрування і псевдослучайная функція використовують два різних ключі.

Допитливий читач може помітити важливу особливість в контексті безпеки. Результат PRF буде завжди одним і тим же для двох однакових фрагментів даних: значення індексів (атрибут Field_A_index) для record_0 і record_1 будуть однаковими, так як вони обидва обчислені по data_1. Це — потенційна витік, тому що сервер на основі аналізу зашифрованих даних та їх індексів (до яких він потенційно має доступ) може визначити, які запису в таблиці містять однакові значення зашифрованих даних з атрибутами, що підтримує пошук (Field_Aв розглянутому випадку). Щоб зменшити негативні наслідки цієї витоку, CipherSweet пропонує зберігати на сервері обрізану значення індексів (табл. 5).

Припустимо, що псевдослучайная функція генерує індекси розміром 64 байта. «Віддаючи» сервера обрізану значення індексу (розмір < 64) можна знижувати наслідки потенційної витоку схеми, тим самим підвищуючи безпеку. Однак при цьому сервер не зможе однозначно визначати записи, які необхідно включати в результат запиту. Тобто зростає ймовірність помилки включення в результат запиту невірної запису (false positive). У цьому випадку на додаток покладається відповідальність «відфільтрувати» всі релевантні запису після отримання результату запиту від сервера і розшифрування даних.

Табл. 5. Усічення індексу в CipherSweet

Records Field_A_index Field_A Field_B
record_0 index_1[64] ENCRYPTED data_2
record_1 index_1[64] ENCRYPTED data_3
record_2 index_4[64] ENCRYPTED data_5
Field_A_index Field_A Field_B
record_0 index_1[<64] ENCRYPTED data_2
record_1 index_1[<64] ENCRYPTED data_3
record_2 index_4[<64] ENCRYPTED data_5

Параметр обрізання (один з параметрів безпеки) може конфігуруватися користувачем. CipherSweet надає спеціальний планувальник для його розрахунку:

<?php
use ParagonIE\CipherSweet\Planner\FieldIndexPlanner;
# First, instantiate the planner for a given field
$planner = new FieldIndexPlanner();
# How many rows do you anticipate?
$planner->setEstimatedPopulation(50000);
 $recommended = $planner->recommend(14);
var_dump($recommended);
 /* array(2) {[min]=>int(8) [max]=>int(14) }*/

Для використання цього планувальника вам необхідно: оцінити очікувану кількість записів, що включають атрибути з зашифрованими даними, і розподілити дані, що підлягають захисту. У наведеному вище прикладі верхня межа очікуваних записів становить 50 000, а бітове розподіл даних (input domain size) — 14 біт. Таке значення розподілу характерно для даних, що визначають роки в календарі: 4 цілі цифри (2019) можуть скласти 10 000 різних комбінацій, отже, розподіл складає log2 (10 000) ? 14. При цьому планувальник рекомендує використовувати індекс з розміром від 8 до 14 біт.

Інтеграція

У попередніх розділах ми розглянули базовий принцип роботи техніки сліпого індексування, реалізованої в CipherSweet. Було показано, які зміни необхідно внести в структуру таблиць бази даних та які криптографічні функції необхідно інтегрувати в додаток для того, щоб активувати шифрування даних програми, що зберігаються на недоверенном віддаленому сервісі, і забезпечити можливість пошуку.

Після вибору прототипу схеми пошукового шифрування перед нашою інженерної командою стояло завдання впровадження схеми у нашу систему комплексного захисту баз даних SQL (Acra [link 1 , link 2 ]).

Центральним компонентом цієї системи є проксі-сервер, ізолюючий функціонал безпеки (шифрування, SQL firewall і Intrusion Detection System) таким чином, щоб робота додатки з базою даних була прозорою (transparent). При цьому програма не потрібна система управління криптографічними ключами і їх зберігання (досить складна проблема, що виникає при впровадженні будь-яких криптографічних операцій): ця функція делегується проксі-сервера.

Використання проксі серверів в комбінації з технікою сліпого індексування дозволяє прозорим для програми чином запровадити можливість пошуку по зашифрованих даних (за рахунок введення додаткового інфраструктурного компонента — proxy (рис. 3)).

Рис. 3. Використання проксі-сервера, що реалізує функціонал безпеки

Для забезпечення прозорості проксі-сервер також відповідає за модифікацію запитів, що надходять від програми, перед відправкою на віддалений сервер управління базою даних (SQL query— початковий запит від програми, SE query— модифікований запит від проксі-сервера).

Нам довелося перенести реалізацію техніки сліпого індексування на Go (CipherSweet вона виконана на PHP і Node.js під вже існуючий проксі-сервер. Криптографічні операції реалізовані з використанням стандартної бібліотеки Go, а також криптографічного бібліотеки Themis . Система є production-ready і DevOps-friendly: підтримує метрики, логування, трейсінг і готова до інтеграції та експлуатації існуючих інфраструктури та додатки.

Зазначимо також, що проксіювання дозволяє усунути незручність, пов'язане з false positives, і ймовірності включення сервером нерелевантних записів з бази даних у результат запиту при усечении індексу з метою підвищення безпеки. Фактично проксі-сервер запам'ятовує запит від програми (SQL query), модифікує його (SE query) відповідно з технікою сліпого індексування, відправляє на сервер і застосовує його до відповіді сервера після розшифрування (decrypted results). Однак при використанні такої фільтрації спостерігається падіння продуктивності, так як нерелевантні записи можуть бути відбраковані тільки після їх розшифрування.

Оцінка продуктивності

Ми оцінювали продуктивність всього рішення на робочій станції з такими характеристиками: Intel Core i7, 4000 MHz (12 ядер), 16 GB RAM під управлінням операційної системи Ubuntu 18.04 LTS (x64). В якості сервісу зберігання даних використовувалася система PostgreSQL (v. 11) у вигляді Docker-контейнера. Вихідний код платформи для тестування продуктивності матеріал, а також всі настройки збережені в GitHub-репозиторії Acra .

Для ініціалізації таблиці в базі даних використовувалися такі SQL-запити:

DROP TABLE IF EXISTS test_raw;
DROP SEQUENCE IF EXISTS test_raw_seq;
CREATE SEQUENCE test_raw_seq START 1;
CREATE TABLE test_raw (id INTEGER PRIMARY KEY DEFAULT nextval('test_raw_seq'), plaintext BYTEA, ciphertext BYTEA).

Стандартний функціональний індекс продуктивності для експериментів з різною величиною скорочення індексу створювався таким SQL-псевдозапросом:

CREATE INDEX IF NOT EXISTS test_raw_ciphertext_secure_index_idx ON test_raw (substr(ciphertext, 1, secureIndexSize));

Проксі-сервер був налаштований на зашифрування і пошук по атрибуту ciphertext. Приклад INSERT-псевдозапроса від додатка:

INSERT INTO test_raw (plaintext, ciphertext) VALUES (input, input);

Приклад SELECT-псевдозапроса від додатка:

SELECT * FROM test_raw WHERE ciphertext=input;

Для оцінки продуктивності ми вимірювали загальний час затримки запитів (query latency) з допомогою такого експерименту:

  1. Генерувався вхідний набір даних (позначимо його R) c n= 50 000 записів шляхом випадкової вибірки з вихідного матеріалу (колекція з 25 000 унікальних імейлів).
  2. Rзаписувався в базу даних.
  3. Вибірка проводилася неіснуючої запису з наступним значенням атрибута ciphertext:ciphertext='\xFFFFFFFFFFFFFFFFFFFFFF', — і виконувалась перевірка того, що у відповіді не було отримано жодного рядка.
  4. Один раз виконувався INSERT-запит з записом r1c однаковим значенням атрибутів ciphertextі plaintext: plaintext = ciphertext = '\x62614C494E31353247444F437177657274793132333435363738393040686f746d61696c2e636f6d', — потім проводилася вибірка r1за вказаним значенням і виконувалась перевірка того, що у відповіді була отримана в точності один запис.
  5. Десять разів виконувався INSERT-запит з записом r2c однаковим значенням атрибутів ciphertextіplaintext, потім проводилася вибірка r2за вказаним значенням і виконувалась перевірка того, що у відповіді було отримано в точності 10 записів.

Такий експеримент проводився з двома вхідними наборами даних з розподілом ключових слів в 350 і 25 000 відповідно.

Табл. 6 узагальнює результати (в середньому за 3 запусків) виконання INSERT-запитів з одним значенням запису.

Табл. 6

.b-typo table.bordered.thick td{border:2px solid #000;text-align:center}
Розподіл ключових слів Виконання запитів без проксі серверів (час з ) Довжина індексу (байти ) Виконання запитів з проксированием Відносне падіння продуктивності
Шифрування
(виклики/час з )
Обчислення індексу (виклики/час в мс ) Інші операції (час з ) Загальне (час з )
350 707.1668 2 50000/57.6947 50000/620.1667 679.0150 737.3299 ~4%
15 50000/57.7494 50000/617.1465 736.5025 794.8690 ~12%
25000 691.9133 2 50000/59.1564 50000/619.2667 648.3589 708.1346 ~2%
15 50000/58.2443 50000/625.7523 670.7465 729.6166 ~5%
.is_mobile .b-typo table tr:first-child td{font-size:10px;min-width:50px;vertical-align:middle;}

Можна помітити, що шифрування займає до 7- 8% всього часу, обчислення індексу — до 1%, а інші операції (мережеве взаємодія і логіка програми) займають 92-93%. Очевидно, що істотна кількість запитів відповідно навантажують мережеву підсистему операційної системи. Цим пояснюється різниця відносних значень падіння продуктивності, отриманих в результаті експерименту.

Приблизне значення падіння продуктивності в цьому випадку знаходиться в межах 2-12%.

Табл. 7 узагальнює результати (в середньому по 10 запусків) виконання INSERT-запитів з 1000 значень записів (так звані bulk-запити).

Табл. 7

.b-typo table.bordered.thick td{border:2px solid #000;text-align:center}
Розподіл ключових слів Виконання запитів без проксі серверів (час з ) Довжина індексу (байти ) Виконання запитів з проксированием Відносне падіння продуктивності
Шифрування
(виклики/час з )
Обчислення індексу (виклики/час в мс ) Інші операції (час з ) Загальна
час в з )
350 2.5993 2 50/23.7783 50000/230.4363 5.2013 29.2100 ~1024%
15 50/23.7612 50000/232.5844 4.5905 28.5843 ~1000%
25000 2.3125 2 50/23.6542 50000/229.2123 4.7324 28.6158 ~1137%
15 50/23.8756 50000/240.4962 4.5991 28.7152 ~1142%
.is_mobile .b-typo table tr:first-child td{font-size:10px;min-width:50px;vertical-align:middle;}

Можна помітити, що в цьому випадку шифрування зайняло до 81-83% часу, обчислення індексу — менше 1%, а мережеві операції — до 18%.

Зазначимо, що в цьому випадку додатком було відправлено лише 50 запитів (у порівнянні з 50 000 в попередньому випробуванні), тому вплив мережевих операцій на продуктивність істотно менше, але все ж помітно.

Падіння продуктивності становить приблизно 1 порядок (10 разів).

Табл. 8 узагальнює результати (в середньому по 10 000 запусків) виконання SELECT-запитів, які повертають у відповіді порожній результат.

Табл. 8

.b-typo table.bordered.thick td{border:2px solid #000;text-align:center}
Розподіл ключових слів Виконання запитів без проксі серверів (час в мс ) Довжина індексу (байти ) Виконання запитів з проксированием Відносне падіння продуктивності
Розшифрування
(виклики/час з )
Фільтрація
(виклики/час у мкс )
Обчислення індексу (виклики/час у мкс ) Інші операції (час в мс ) Загальна
(час в мс )
350 0.1840 2 1/41.9543 0.4933 0.5353 ~191%
15 1/39.1419 0.4623 0.5014 ~172%
25000 0.1770 2 1/37.7230 0.4397 0.4774 ~170%
15 1/38.6630 0.4577 0.4964 ~180%
.is_mobile .b-typo table tr:first-child td{font-size:10px;min-width:50px;vertical-align:middle;}

Можна бачити, що мережеві операції зайняли до 92% всього часу, а обчислення індексу — 8%. Очевидно, що в цьому випадку не повинні проводитися операції розшифрування та фільтрації.

Приблизне значення відносного падіння продуктивності склало 170-191%.

Табл. 9 узагальнює результати (в середньому по 10 000 запусків) виконання SELECT-запитів, повертають в точності 1 запис у відповіді.

Табл. 9

.b-typo table.bordered.thick td{border:2px solid #000;text-align:center}
Розподіл ключових слів Виконання запитів без проксі серверів (час в мс ) Довжина індексу (байти ) Виконання запитів з проксированием Відносне падіння продуктивності
Розшифрування
(виклики/час з )
Фільтрація
(виклики/час у мкс )
Обчислення індексу (виклики/час у мкс ) Інші операції (час в мс ) Загальна
(час в мс )
350 0.1920 2 1/0.4988 1/32.2792 0.5747 1.1058 ~476%
15 1/0.4971 1/28.9147 0.5700 1.0960 ~471%
25000 0.1920 2 3/1.3528 2/73.6460 1/30.6646 0.6666 2.1237 ~1006%
15 1/0.5000 1/32.3181 0.5795 1.1120 ~479%
.is_mobile .b-typo table tr:first-child td{font-size:10px;min-width:50px;vertical-align:middle;}

Можна помітити, що в експерименті з набором даних з розподілом 25 000 ключових слів і коротким індексом (2 байти) розшифрування займає значно більше часу, ніж в експериментах з іншими параметрами. Трейсы показали, що функція розшифрування була викликана 3 рази замість 1 очікуваного. Також 2 рази була викликана функція фільтрування. Це пояснює той факт, що у відповіді від сервера містилися 2 нерелевантні рядки, які були відфільтровані після розшифрування.

В результаті значення падіння продуктивності істотно коливається (в межах 471-1006%).

Табл. 10 узагальнює результати (в середньому по 10 000 запусків) виконання SELECT-запитів, повертають в точності 10 записів у відповіді.

Знову можна помітити наявність «порожніх» операцій розшифрування та фільтрацію в експерименті з набором даних з розподілом 25 000 ключових слів і коротким індексом.

Відносна величина падіння продуктивності знаходиться в межах 1934-2630%.

Табл. 10

.b-typo table.bordered.thick td{border:2px solid #000;text-align:center}
Розподіл ключових слів Виконання запитів без проксі серверів (час в мс ) Довжина індексу (байти ) Виконання запитів з проксированием Відносне падіння продуктивності
Розшифрування
(виклики/час з )
Фільтрація
(виклики/час у мкс )
Обчислення індексу (виклики/час у мкс ) Інші операції (час в мс ) Загальна
(час в мс )
350 0.2410 2 10/4.2650 1/29.7211 0.9265 5.2212 ~2066%
15 10/4.2619 1/28.9147 0.9682 5.2590 ~2082%
25000 0.2550 2 14/5.8788 4/69.5195 1/30.0456 0.9842 6.9626 ~2630%
15 10/4.2538 1/32.9155 0.9051 5.1878 ~1934%
.is_mobile .b-typo table tr:first-child td{font-size:10px;min-width:50px;vertical-align:middle;}

Згідно з результатами з табл. 2-6 можна констатувати, що проксіювання вносить досить значне падіння продуктивності (аж до 2 разів). Найбільш істотний вплив роблять криптографічні операції (шифрування і розшифрування). Також слід зазначити, що результати SELECT-запитів можуть містити нерелевантні запису при коротких (1- 2 байти) значеннях індексів. Це може призводити до «порожнім» викликів функцій розшифрування та подальшого погіршення продуктивності.

Висновок

Пошукове шифрування — відносно новий напрямок у сучасній криптографії. Його актуальність вкрай висока у зв'язку з тим, що з'являється все більше нормативних вимог (наприклад, GDPR і HIPAA) до зберігання конфіденційних даних в зашифрованому вигляді при використанні хмарних/віддалених сервісів. В той же час потрібна можливість ефективного пошуку зашифрованими даними. Незважаючи на велику кількість існуючих академічних досліджень (запропоновано понад 50 схем пошукового шифрування), вони не можуть бути реалізовані у вигляді практичних, продуктивних і безпечних рішень (зокрема, для баз даних SQL), які могли б застосовуватися в production-ready-системах і додатках, у зв'язку зі складними протиріччями у вимогах до таких систем.

На наш погляд, ключові особливості, якими повинна володіти система пошукового шифрування, це:

При цьому допустимо жертвувати продуктивністю за рахунок збільшення рівня безпеки даних. У цьому контексті найбільш перспективною виглядає схема CipherSweet, що реалізує техніку сліпого індексування. На відміну від багатьох підходів, пропонованих академічним співтовариством, ця техніка дуже практична з інженерної точки зору, а також володіє достатньо високим ступенем безпеки за рахунок простоти і зрозумілості криптографічного дизайну.

Список джерел додаткової інформації

Опубліковано: 11/12/19 @ 11:08
Розділ Різне

Рекомендуємо:

ІТ-волонтери: як викладач створив додаток про втрачену архітектурній спадщині Харкова
QA дайджест #40: лайфхаки автоматизації, добірка книг для тестувальників
9 способів чистити пошукові запити в Key Collector
Безпека в інтернеті, або TrustedTypes як новий спосіб захисту від XSS
Микросервисный підхід у веб-розробці: micro frontends