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

Эта статья посвящена новому способу защиты БД Access. Он имеет ряд преимуществ над существующими методами, которые я описал в статье Защита и взлом баз данных Access

Введение

Известно, что на сегодняшний день не существует способа защитить значения, хранимые в таблицах БД Access от прямого доступа. Либо защита удаляется с помощью программ типа dbRecowery, либо она накладывает серьёзные ограничения на производительность приложений работающих с БД и всё равно взламываются, но с большими трудозатратами.

Вот достоинства предлагаемого способа:

  • защита устанавливается и снимается нажатием одной кнопки
  • добавление защиты в код - добавление одной строки при подключении БД и изменить строку с паролем в коде.(больше ни чего менять не надо)
  • её нельзя снять программами типа dbRecowery
  • её использование почти не сказывается на производительности
  • можно использовать ADO или DAO
  • защищающий код можно интегрировать в VB проект (2 класса и 2 модуля)
  • не надо платить за программы и электронные ключи

Вот его недостатки:

  • реализовано в виде Active-X dll на Visual Basic 6 (не удалось сделать на VBA)
  • работает только на чтение данных (запись не реализована)
  • работает под WinXP; должно работать под 2k; под 98 - не работает (надо доделывать)

О тестовом проекте

  • data.mdb - защищенная БД с двумя таблицами и одним запросом
  • user.mdb - БД с формой 'main' в которую выводятся данные из data.mdb с помощью Protect.dll
  • Protect.dll - ищет data.mdb в той же директории, где и сама и возвращает ADODB.Recordset для регистрации необходимо выполнить в командной строке 'regsvr32.exe [Ваш путь к]\Protect.dll'

Описание способа защиты

Данный способ основан на использовании прозрачного шифрования. При таком подходе работающая с данными программа не замечает, что данные зашифрованы. Иными словами, когда библиотеки ADODB нашей программы обращаются к файлу БД - они видят самый обычный файл. Но если с этими данными начинает работать чужая программа - она видит зашифрованные данные. Подобный подход используется в HASP Envelope. Но с его помощью шифруется весь файл, что сильно снижает производительность. Между тем, достаточно зашифровать только заголовок БД чтобы получить приемлемый уровень защиты.

Для работы с БД Access в настоящее время используется ADODB. Сначала создаётся подключение к файлу БД (ADODB.Connection). Когда заданы все параметры подключения - вызывается метод Open, который открывает БД. При этом, происходит чтение первых &H10000 байт файла БД. Здесь и срабатывает защита. Мы эти &H10000 байт предварительно зашифруем. Программа перехватывает вызов API функции ReadFile, сама считывает заголовок БД, и возвращает дешифрованные данные.

Чтобы перехватить вызов API функции ReadFile необходимо сделать следующее:

  • получить идентификатор процесса с помощью функции GetCurrentProcessId
  • получить описатель процесса, используя OpenProcess
  • получить адрес замещающей функции, используя AddressOf
  • получить описатель модуля kernel32 с помощью GetModuleHandle
  • получить адрес функции ReadFile с помощью GetProcAddress
  • прочитать и сохранить первые оригинальные 6 байт стандартной API функции ReadFile с помощью ReadProcessMemory
  • записать с помощью WriteProcessMemory вместо этих 6 байт код ASM инструкции push и ret, указав в качестве аргумента инструкции push адрес замещающей функции

Таким образом, сначала мы меняем код API функции ReadFile на вызов нашей замещающей функции. Поле вызова метода Open объекта Connection - одна из библиотек ADODB начинает читать файл БД, используя ReadFile. Так как эта функция была нами модифицирована - она обращается к замещающей функции.

Замещающая функция имеет тот же набор аргументов, что и оригинальная ReadFile. Таким образом, получив управление в свои руки, мы знаем - откуда и сколько надо считать и куда результат поместить. При вызове замещающеё функции происходит следующее:

  • возвращаем оригинальные 6 байт стандартной API функции ReadFile на место с помощью WriteProcessMemory
  • вызываем ReadFile с теми же аргументами, с какими её вызывала библиотека ADODB
  • так как нам известен размер считанных данных и адрес, куда они были прочитаны - мы дешифруем эти данные
  • всё. библиотека ADODB получает управление обратно, даже не заметив наших действий. С её точки зрения - она просто вызвала функцию ReadFile, которая считала блок данных из файла. Повторное чтение файла функцией ReadFile будет происходить как обычно, так как мы вернули её в исходное состояние

Развитие проекта

  • Этот материал ранее был опубликован на sql.ru в форуме по Access
  • Предлагаю поучаствовать в дальнейшем совершенствовании этой технологии. На мой взгляд, она достаточно эффективна в плане защиты, проста в использовании и пригодна для добавления в существующие проекты
  • Может, кому удастся перевести код на VBA. Основная проблема в использовании AddressOf. В таком случае можно будет интегрировать код в mde файл, и избежать той глупой ошибки, которую я допустил, возвращая Recordset из Active-X dll
  • Также можно реализовать не только чтение, но и запись заголовка и сделать возможной работу под win98

Скачать пример Sample.zip 131 КБ

 


Страница сайта http://silicontaiga.ru
Оригинал находится по адресу http://silicontaiga.ru/home.asp?artId=4759