До момента разгледахме в технологията на цифровия подпис, инфраструктурата на публичния ключ и средствата на Java платформата за работа с цифрови подписи, сертификати и смарт карти. Направихме и анализ на съществуващите технологии за използване на цифров подпис в уеб и стигнахме до решението да използваме Java аплет за подписване на документи в уеб браузъра на потребителя преди изпращането им към сървъра. За да е напълно функционална нашата система за цифрово подписване на документи в уеб среда, ще добавим към нея и модул за верификация на цифровите подписи и сертификати, получени от клиентския уеб браузър.
Нека разгледаме в детайли проблемите, свързани с реализацията на такава система. Ще започнем от нейната архитектура и ще продължим по-нататък с конкретната имплементация.
2.1.Архитектура на системата
Системата за цифрово подписване на документи в уеб среда и верификация на цифрови подписи и сертификати, която ще разработим, е базирана на класическа клиент-сървър архитектура, реализирана чрез уеб браузър и уеб приложение (фигура 3-1):
Фигура 3 16. Архитектура на системата за подписване на документи в уеб среда
Тя се състои от следните компоненти:
DigitalSignerApplet – Java аплет за подписване на документи в уеб браузъра на потребителя със сертификат от PKCS#12 хранилище.
SmartCardSignerApplet – Java аплет за подписване на документи в уеб браузъра на потребителя със смарт карта.
DocumentSigningDemoWebApp – Java-базирано уеб приложение за посрещане на подписан документ и верификация на неговия цифров подписи и сертификат. Приложението включва подсистема за верификация на цифрови подписи, подсистема за директна верификация на сертификат и подсистема за верификация на сертификационна верига.
От страна на клиента работи стандартен уеб браузър, в който се изпълняват Java аплети за подписване на документи. Подписаните документи се изпращат към уеб сървъра чрез стандартна уеб форма по протокол HTTP. Подписването чрез сертификат от PKCS#12 хранилище и подписването със смарт карта се реализират поотделно от два различни Java аплета.
От страна на сървъра работи Java-базирано уеб приложение, което посреща подписаните документи и проверява цифровия им подпис, както и сертификата, с който са подписани. Ако сертификатът пристига заедно със сертификационната си верига, тя също се верифицира. Реализирани са два метода за верификация – директна проверка на сертификат и проверка на сертификационна верига.
При директната проверка на сертификат се проверява дали сертификатът е валиден към датата на проверката и дали е подписан (издаден) от някой от сертификатите, на които сървърът има директно доверие.
При проверката на сертификационната верига даден сертификат се счита за валиден, ако е валидна веригата му и ако тя завършва с Root-сертификат на който сървърът има доверие.
Нека сега разгледаме в детайли отделните компоненти на системата.
2.2.Java аплет за подписване на документи
Сега ще разгледаме конкретните проблеми, които възникват при реализацията на Java аплет, който служи за подписване на документи в клиентския уеб браузър. Разликата между аплета, който подписва със сертификат, извлечен от PKCS#12 файл и аплета, който подписва със смарт карта, е минимална, така че ще разгледаме и двата едновременно.
2.2.1.Подписани Java аплети
Нека разгледаме в детайли технологията на подписаните аплети, защото ще трябва да я използваме за да повишим правата, с които се изпълнява нашият аплет.
Необходим е достъп до файловата система
Аплетът, който разработваме, трябва да може да подписва файлове от локалната машина и следователно трябва да може да ги чете. По принцип Java аплетите се изпълняват с намалени права и нямат достъп до файловата система на машината, на която работят. За да се преодолее това ограничение, е необходимо аплетът да работи с пълни права, а за тази цел той трябва да бъде подписан.
За да повишим правата, с които се изпълнява даден аплет, е необходимо да го подпишем. Нека разгледаме как става това.
Да предположим, че сме написали кода на даден аплет и след като сме го компилирали, сме получили файла Applet.jar. Необходимо е да подпишем този JAR файл.
Можем да използваме за целта програмката jarsigner, която се разпространява стандартно с JDK 1.4. По подразбиране тя се инсталира в директория %JAVA_HOME%\bin. Ето един пример за нейното използване:
Посочената команда подписва JAR файла Applet.jar с личния ключ, записан под име signFilesAlias в хранилището за сертификати и ключове keystore.pfx като използва пароли за достъп до хранилището и сертификата съответно store_password и private_key_password.
Програмката jarsigner поддържа два типа хранилища за сертификати и ключове – Java Key Store (.JKS файлове) и PKCS#12 (.PFX файлове). За да я използваме, трябва или да имаме сертификат, издаден от някой сертификационен орган (PFX файл, съдържащ сертификата и съответния му личен ключ) или трябва да си генерираме саморъчно-подписан сертификат. От JDK 1.5jarsigner поддържа подписване и със смарт карта.
Генериране на саморъчно подписани сертификати с jarsigner
За да си генерираме саморъчно-подписан (self-signed) сертификат можем да използваме програмката keytool, която идва стандартно с JDK 1.4.
Ето примерна команда за генериране на саморъчно-подписан сертификат:
Посочената команда генерира X.509 сертификат и съответен на него личен ключ и ги записва под име signFiles в хранилището за ключове и сертификати SignApplet.jks. В сертификата се записва, че собственикът му е “My Company”, а за парола за достъп до хранилището и до личния ключ се използва “!secret”. По подразбиране програмката keytool използва формата за хранилища JKS (Java Key Store).
Подписване на аплет със саморъчно-подписан сертификат
Можем да използваме генерирания с предходната команда саморъчно-подписан сертификат за да подпишем нашия аплет по следния начин:
Тази команда подписва аплета Applet.jar с личния ключ, записан под име “signFiles” в хранилището SignApplet.jks, използвайки парола за достъп “!secret”. В резултат се получава подписан JAR файл, който съдържа всички файлове от архива Applet.jar, заедно с цифровите сигнатури на тези файлове и сертификата от хранилището SignApplet.jks заедно с пълната му сертификационна верига. Ако не се зададе име на файл, в който да се запише резултатът, както е в посочения пример, за изходен JAR файл се използва входният JAR файл.
Кодът, с който един подписан аплет се вгражда в един HTML документ, не се различава от HTML кода, с който се вгражда обикновен аплет. Все пак, когато се използват подписани аплети, не се препоръчва да се ползва остарелият таг , защото при него няма начин да се укаже минималната версия на JDK, която е необходима за нормалната работа на аплета.
Някои уеб браузъри (например Internet Explorer) стандартно поддържат JDK версия 1.1 и ако не се укаже, че подписаният аплет изисква по-висока версия на виртуалната машина, този аплет или стартира с ограничени права и съответно не работи правилно или въобще не стартира.
За да се избегнат такива проблеми се препоръчва да се използват таговете в Internet Explorer или в останалите браузъри и в тях да се укаже минималната версия на JDK, която е необходима на аплета. За автоматично преобразуване на тага към по-новите тагове за вграждане на аплети към JDK 1.4 има специална помощна програмка HtmlConverter.exe.
Предупреждение за изпълнение на подписани аплети
Средата, която изпълнява аплети в уеб браузъра на клиента (обикновено това е Java Plug-In), има грижата да прецени дали даден аплет е подписан или не. Ако един аплет е подписан, при зареждането му се появява диалог, който предупреждава, че е зареден подписан аплет, който изисква пълни права върху клиентската система, за да работи нормално (фигура 3-2).
Java Plug-In дава подробна информация за сертификата, с който този аплет е подписан, съобщава дали е валиден, след което пита потребителя дали да изпълни аплета без ограничения на правата. Ако потребителят се съгласи, аплетът се стартира с пълни права, а в противен случай се изпълнява като нормален (неподписан) аплет. Възможно е да се даде и перманентно доверие на аплета за да не се показва предупреждението при всяко негово зареждане.
Фигура 3 17. Диалог-предупреждение на Java Plug-In 1.5 за подписан аплет
2.2.2.Връзка между Java аплет и уеб браузър
Нека сега разгледаме един друг проблем. Аплетът, който трябва да подписва документи, трябва по някакъв начин да изпраща на сървъра изчислената цифрова сигнатура.
Това може да се реализира по няколко начина – аплетът или отваря сокет към сървъра и му изпраща сигнатурата през този сокет, или изпраща информацията чрез заявка за достъп до някой сървърен URL или си комуникира с уеб браузъра и изпраща информацията към него, а той я препраща към сървъра.
Последната възможност е най-удобна, защото изисква най-малко усилия от страна на програмиста, за да бъде изпратен и приет един подписан файл. В този случай сървърът може да получава файла заедно с подписа наведнъж с една единствена заявка от браузъра без да са необходими никакви други действия.
Достъп до HTML форма от Java аплет
Да предположим, че имаме обикновена HTML форма, с която се изпращат файлове към дадено уеб приложение без да бъдат подписвани. Ако искаме да разширим тази форма, така че да поддържа и цифрови подписи, можем да интегрираме в нея Java аплет за подписване на файлове.
Ако имаме аплет, който изчислява цифрова сигнатура на даден файл и поставя тази сигнатура в някакво поле на тази HTML форма, усилията необходими за изпращане на цифровия подпис към сървъра ще са минимални. Уеб браузърът, когато изпраща HTML формата, ще изпрати заедно с нея и цифровия подпис и така няма да има нужда Java аплетът да се занимава с комуникация между клиента и сървъра.
Стандартно Java аплетите могат да осъществяват достъп до HTML страницата, от която са заредени. Тази възможност може да бъде използвана за да се вземе от HTML формата името на файла, който потребителят ще изпраща, за да бъде прочетено и подписано съдържанието на този файл. Резултатът от подписването може да бъде върнат в някое поле от същата HTML форма. Да разгледаме техническите средства за връзка между java аплет и уеб браузър.
Класът netscape.javascript.JSObject
Технически взаимодействие между аплет и уеб браузър може да се реализира чрез стандартния клас netscape.javascript.JSObject, който е достъпен от всички браузъри, поддържащи аплети. Този клас предоставя функционалност за достъп до обектния модел (всички методи и свойства) на текущия прозорец на уеб браузъра, от който е бил зареден аплета, а това означава, че от аплет можем да имаме достъп до HTML документа зареден в този прозорец, до HTML формите в него, до полетата в тези форми и въобще до всичко, до което можем да имаме достъп с JavaScript [J2JS, 2004].
Класът JSObject поддържа статичен метод getWindow(), с който се извлича от уеб браузъра прозорецът, в който се намира аплетът. След това може да се осъществява достъп до обектния модел на този прозорец и документа, показан в него, чрез методите getMember(), setMember() и eval().
Ето част от сорс кода на аплет, който извлича стойността на полето с име FileName от първата HTML форма на уеб страницата от която е зареден:
String fileName = (String) fileNameField.getMember("value");
// Continue the applet initialization here ...
}
Някои браузъри позволяват на аплетите да изпълняват JavaScript и да осъществяват достъп до HTML документа, от който са заредени, само ако това е изрично указано чрез параметри на тага, с който те се вграждат в документа. Такива са параметрите “mayscript” и “scriptable” и те трябва да имат стойност “true”.
Проблеми при достъп до аплет от JavaScript
По принцип има и още една възможност за осъществяване на комуникацията между аплета и браузъра – вместо аплетът да записва в поле от формата резултата от изчислението на цифровата сигнатура на изпращания файл, от JavaScript функция би могъл да се извиква някакъв метод на аплета, който да връща цифровия подпис и след това също с JavaScript да се записва този подпис в някое поле от формата.
Описаният подход не работи винаги, защото в някои уеб браузъри JavaScript кодът се изпълнява с такива права, че не може да осъществява достъп до файловата система. Независимо, че аплетът е подписан и може да чете локални файлове, ако бъде извикан негов метод от JavaScript, този метод ще работи с намалени права. Това поведение може да е различно при различните уеб браузъри, но при всички случаи създава неприятности.
2.2.3.Проектиране на аплета за подписване
Нека сега проектираме конкретната функционалност на аплета за подписване на документи в уеб среда и опишем начинът му на работа.
Подписаният аплет трябва да се извиква директно от потребителя
Поради описаните преди малко проблеми вместо да извикваме Java функция за подписване на файл от JavaScript, е много по-добре да направим аплетът да има формата на бутон, който при натискане да подписва избрания от потребителя файл и да записва изчислената сигнатура в определено поле на HTML формата.
По желание може да се накара аплетът чрез JavaScript автоматично да изпраща HTML формата след изчисляване на сигнатурата за да не може потребителят да промени нещо по тази форма след извършване на подписването. В такъв случай може да е удобно HTML формата да няма бутон за изпращане и изпращането й да става единствено от аплета и то само след успешно подписване. Така потребителят няма да има възможност да изпраща неподписани или грешно подписани файлове.
Сървърът получава документа, подпис и сертификат
При подписване на документ е необходимо на сървъра да се изпраща не само документът и изчисления от него цифров подпис, но също и сертификатът, използван при подписването, придружен от цялата му сертификационна верига (ако е налична).
Сертификатът е необходим, защото в него се съхранява публичният ключ на потребителя, извършил подписването, а без него не може да се верифицира подписът. Освен това сертификатът свързва този публичен ключ с конкретно лице, извършило подписването.
Ако изпращаме на сървъра само документа, сигнатурата и публичния ключ, ще можем да проверим валидността на сигнатурата, но няма да имаме информация кое е лицето, което притежава този публичния ключ, освен ако сървърът няма някакъв списък от публичните ключове на всички свои клиенти.
В общия случай най-удобно е на сървъра да се изпраща сертификатът на потребителя заедно със сертификационната му верига, за да може тя да бъде верифицирана след като бъде получена.
Процесът на подписване на документ
Самият процес на подписване, който започва при натискане на бутона от аплета за подписване, може да се извърши по следния начин:
Подканва се потребителят да избере от локалната си файлова система защитено хранилище (PFX файл), съдържащо цифровия му сертификат и съответните на него личен ключ и сертификационна верига. Изисква се от потребителя да въведе паролата си за достъп до информацията в избраното защитено хранилище. Ако се използва смарт карта, се подканва потребителят да посочи библиотеката-имплементация на PKCS#11 и PIN кодът за достъп до смарт картата.
Зарежда се избраният PFX файл и от него се изваждат сертификата на потребителя, съответният му личен ключ и цялата сертификационна верига, свързана с този сертификат. При работа със смарт карта случаят е аналогичен – от картата се зареждат сертификатът, сертификационната му верига (ако е налична) и личният ключ.
Взема се името на файла за подписване от HTML формата, файлът се зарежда в паметта и се извършва подписването му с личния ключ на потребителя.
Резултатът от подписването на файла и сертификата на потребителя заедно с цялата му сертификационна верига се записват в определени полета от HTML формата в текстов вид за да бъдат изпратени към сървъра заедно в уеб формата. Може да се използва стандартният формат BASE64 за записване на бинарни данни в текстов вид.
Сървърът, който посреща подписания файл, има грижата да провери дали файлът е коректно подписан с личния ключ, съответстващ на изпратения сертификат. Освен това сървърът трябва на даден етап да проверява дали използваният сертификат е валиден. Това може да става веднага при получаването на файла или на по-късен етап, ако е необходимо да се установи от кого е подписан даден документ.