Активная защита баз данных
Объяснение принципов работы
Представим, что в нашей системе работают два пользователя. Один хороший, другой плохой. Хороший пользователь берет приходную накладную и аккуратно, без ошибок вводит ее в базу данных. После чего плохой пользователь меняет в этой накладной одну строчку. Например:
хорошая вещь 110 шт. Х 101 руб. = 11110 руб.
меняется на:
хорошая вещь 101 шт. Х 110 руб. = 11110 руб.
Не сразу и заметишь - что изменилось, не правда ли? Однако теперь плохой пользователь, не привлекая особого внимания, может забрать себе 9 шт.

Как хорошему пользователю защитить себя от действий плохого?
В этом месте обычно говорится:
Ну, у нас есть система хранения версий. Мы можем увидеть все, что происходило с этим документом.
Где здесь ошибка? В слове "можем". Чтобы что-то увидеть, надо знать куда смотреть. Допустим, в нашей относительно скромной базе данных хранятся данные о 10 тысячах документов в виде 15 тысяч различных версий. Есть, например, один документ и 10 исправлений этого документа. Выглядит подозрительно, но плохой пользователь не делал 10 исправлений, он сделал одно. Надо проверять все документы, имеющие хотя бы одно исправление, а таких много. Можно было бы проверить все документы, где количество и цена менялись местами. Но действия плохого пользователя неотличимы от обычной операторской ошибки. Исправили ошибку и теперь все верно? Или специально испортили документ? Нет другого способа выяснить что произошло на самом деле, кроме как свериться с первичным документом.

Допустим, хороший пользователь решает тогда проверять документы не только при вводе, но и при каждом изменении кем бы то ни было. Что это будет означать для плохого пользователя? Всего лишь то, что ему следует быть чуть более предусмотрительным. Он уже нашел способ изменить документ так, чтобы не возникло вопросов извне, т.е. у поставщика в нашем случае. Теперь ему надо изменить документ так, чтобы и внутри никто не мог отследить факт изменения.

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

В чем ее слабость. В системе всегда есть как минимум один, а еще чаще несколько пользователей с исключительными правами. Более того, во всякой системе есть какое-то количество способов повысить права обычного пользователя до исключительного уровня. Т.е. в системе пассивной защиты всегда есть незакрытые "черные ходы". Какие-то не закрыты потому что о них пока еще мало кто знает (но наш плохой пользователь может оказаться в узком кругу осведомленных). Другие относятся к разряду общеизвестных, но их все равно не закрывают по тем или иным причинам. Самое главное - у нас нет никаких оснований надеяться на то, что плохой пользователь сообщит нам о том, что наша пассивная защита не работает.

Пассивная защита должна быть дополнена активной. Это означает, что кто-то должен обеспечивать постоянный контакт базы данных с реальностью. Документы проверяются в момент ввода и перепроверяются при каждом изменении. В чем здесь фундаментальная сложность. Допустим у нас есть документ, отмеченный каким-то образом как измененный. Хороший пользователь проверяет его и... снимает отметку изменения. Конечно он должен сделать это. Иначе ему придется проверять этот документ повторно. Но если хороший пользователь может снять отметку изменения документа, то почему плохой не может сделать то же самое? Получается, что мы не можем полагаться на отметки об изменении документов и нам остается только одно. Каждый раз мы должны проверять абсолютно все документы в базе данных, а это невозможно. Где здесь ошибка? В слове "невозможно".

Уже достаточно давно существуют относительно простые и хорошо проверенные технологии, которые при правильном соединении дают возможность контролировать любые объемы данных.

Первый ингредиент нашего "блюда" называется: хеш-функция. Хеш-функция преобразует данные произвольного объема в строку фиксированной длины. Звучит просто, но сами хеш-функции не столь просты. В нашем случае мы будем иметь дело с превращением гигабайтов данных в относительно короткую строку. Такую, которую можно было бы контролировать визуально. Как превратить миллиард байт в 32? Действуя прямолинейно, можно было бы оставить случайные 32 байта, а остальное отбросить. Хеш-функция действует более изощренно. Прежде чем отбросить лишнее, данные тщательно перемешиваются, превращаются в самый настоящий фарш (hash). Причем, этот фарш не просто идеален. Он фантастически идеален. Представьте себе фото достаточно высокого качества. Вы изменяете всего лишь один бит в этом фото. Один единственный пиксель слегка изменил свой оттенок. Теперь у вас два практически неотличимых друг от друга фото. Если применить прямолинейный подход, тогда с огромной вероятностью оба фото дадут на выходе одни и те же 32 байта. А вот хеш-функция с вероятностью, которую можно считать равной единице, выдаст разные 32 байта. Причем, сильно разные. Настолько, что это можно будет заметить с одного взгляда.

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

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

Блокчейн - технология, ставшая широко известной с появлением криптовалют. Хотя открыта она была задолго до этого. Что нам дает журнал в виде блокчейна. Каждый хеш соответствует своему документу. Мы всегда можем проверить это соответствие. Одновременно, каждый хеш соответствует сразу всем предыдущим документам. Это означает, что нельзя просто подменить какую-либо запись в журнале. Придется пересчитать все хеши от измененной записи до конца. А это уже легко обнаружить.

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

Что получил хороший пользователь. Ровно то, что ему было нужно. У него есть журнал, в который попадают все новые документы, а также все измененные документы. Изменить документ незаметно для хорошего пользователя не получится. Любые изменения будут "всплывать" в журнале. Все, что остается плохому пользователю - это подменить сам журнал. Но и это не выйдет, так как у хорошего пользователя всегда есть последний хеш, а значит он сразу же заметит подмену журнала.

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