Пример практического применения механизма электронно-цифровой подписи

© Пономаренко Н.
Мариуполь 2003 г.

Для чего это нужно

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

Пример реализован в среде Delphi 6, СУБД Interbase/Firebird, компоненты доступа InterBase Express (IBX), шифрование - LockBox . Для получения хеша используется алгоритм MD5, шифрование RSA.

В БД заведена таблица документов DOCUMENTS, подлинность которых нам и нужно контролировать, таблица DOCUMENT_SIGNS - подписи документов определенными пользователями из таблицы USERS.

Логика работы

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

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

Хеш документа вычисляется на сервере (что б не гонять зря данные) с помощью UDF. Для этого реализованы две функции - хеширование блоба (md5_blob) и хеширование строки (md5_string). Если документ хранится как блоб то все просто, а если как набор полей, то можно считать хеш от строки, состоящей из конкатенированных полей ( select md5_string(d.doc_f2||d.doc_f1) from documents d). В последнем случае помним: поля на основании которых вычисляется хеш не должны быть nullable - null+value=null, сумма длин всех полей не более максимальной длинны строки СУБД.

Расшифровка подписи выполняется в клиентском приложении, но никто не мешает вынести их в udf.

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

Пример

Пример состоит из двух приложений - клиентского и административного. Для его работы нужно иметь установленный сервер СУБД.


Администраторский интерфейс.

Генерация пар ключей, назначение публичного ключа пользователю, сохранение приватного ключа в файл. Важен размер ключа, для клиентского приложения он "зашит" в код (1024).


Клиентский интерфейс.

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

Заключение

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

Приложения

Исходные тексты + БДdig_sign.zip (51.1К)
LockBoxtplockbox_2_07.zip (315К)

Copyright © 2003 Николай Пономаренко  Специально для Delphi Plus

Rambler's Top100