Подписи в аплетах — как это делается ?
Решил подготовить небольшую статью о том, как создаются подписи для аплетов и как это все работает.
Все примеры проверялись с установленным JRE 1.4.2 — так что если вы не установили хоть какую-то JRE, работать не будет ничего. Если же установили, но другой версии, то возможно, что работать будет не совсем так, как описано.
В этом случае я жду Ваших пожеланий и комментариев. Текст программы я сочинил не сам — подсмотрел. Но все остальное проверил и протестировал. Так что пользуйтесь 🙂
Итак, начнем с самого начала и напишем небольшой аплет, который умеет читать файл с диска.
Вот сам код аплета
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
// file ReadFileApplet import java.applet.*; import java.awt.*; import java.awt.event.*; import java.io.*; public class ReadFileApplet extends Applet { TextArea text = new TextArea(); Button goButton = new Button("Read Local File"); Panel panel = new Panel(); String fileName = ""; public void init() { fileName = getParameter("fileName"); setLayout(new BorderLayout()); goButton.addActionListener(new ButtonHandler()); panel.add(goButton); add("North", panel); add("Center", text); } class ButtonHandler implements ActionListener { public void actionPerformed(ActionEvent e) { String s = e.getActionCommand(); if("Read Local File".equals(s)) { try { FileInputStream inStream = new FileInputStream(fileName); int inBytes = inStream.available(); byte inBuf[] = new byte[inBytes]; int bytesread = inStream.read(inBuf, 0, inBytes); text.setText(new String(inBuf)); } catch(Exception ex) { text.setText(ex.toString()); } } } } } |
А вот и примерчик HTML (ReadFileApplet.htm), который запустит ваш код.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<HTML> <HEAD> <TITLE>Аплет, который читает локальные файлы</TITLE> </HEAD> <BODY> <H1>Аплет, который читает локальные файлы</H1> <APPLET CODE="ReadFileApplet.class" ARCHIVE="rfa.jar" HEIGHT=300 WIDTH=600> <PARAM NAME="fileName" VALUE="C:\AUTOEXEC.BAT"> Текст, выводимый броузерами, не поддерживающими Java. </APPLET> </BODY> </HTML> |
После того, как вы скопировали эти примеры :), давайте их соберем в JAR-архив. Первым делом запустим компилятор JAVA,
1 |
javac ReadFileApplet.java |
а второй командой соберем получившиеся class-файлы в JAR-архив
1 |
jar cf rfa.jar ReadFileApplet*.class |
Ключ c говорит о том, что надо создать архив. Ключ f говорит что надо отправить результат в файл rfa.jar. Последним идет список фалов. Теперь у нас есть JAR-файл и вы можете (это лучше сделать сейчас) удалить файлы *.class.
Итак, мы подготовили обычный аплет. Давайте проверим его работоспособность. Запускаем:
1 |
appletviewer ReadFileApplet.htm |
Аплет по идее должен загрузиться и мы теперь нажимаем кнопку «Read Local File». И получаем само собой предупреждение, что мы этого не можем делать
java.security.AccessControlException: access denied (java.io.FilePermission C:\AUTOEXEC.BAT read)
Как видим, поведение совершенно правильное, ибо нефиг локальные файлы читать всяким аплетам.
Теперь приступим к подписанию нашего аплета. Первое, что мы должны сделать, это сгенерировать пару ключей закрытый/открытый и поместить эту пару в некое хранилище. Для серьезных приложений такие хранилища в Интеренете содержат специальные уполномоченные фирмы.
Нам это в данный момент недоступно и мы создадим свое локальное хранилище. Итак, запускаем следующую команду
1 |
keytool -genkey -keystore .keystore -alias "Vingrad" |
Утилита keytool предназначена для многих целей, но мы ее используем для генерации ключа. Что указывает ключ -genkey. Пара ключей помещается в файл-хранилище .keystore (это говорит опция -keystore) и этой паре присваивается алиас «Vingrad» (ключ -alias)
Сначала утилита спросит пароль для хранилища. Можно ввести что-то запоминающееся — например, 123456.
Запомните этот пароль — он нам еще пригодится.
После этого будут заданы вопросы, на которые можно просто нажимать <ENTER>. Только подтверждение должно содержать yes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Enter keystore password: 123456 What is your first and last name? [Unknown]: What is the name of your organizational unit? [Unknown]: What is the name of your organization? [Unknown]: What is the name of your City or Locality? [Unknown]: What is the name of your State or Province? [Unknown]: What is the two-letter country code for this unit? [Unknown]: Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct? [no]: yes Enter key password for <Vingrad> (RETURN if same as keystore password): |
Теперь по идее в нашем каталоге появился файл .keystore. И теперь мы можем подписать наш JAR-архив. Для подписи арзива используем утилитуjarsigner.
ОБЯЗАТЕЛЬНО: Не забудьте выйти из appletviewer, т.к. в противном случае JAR-файл невозможно будет изменить
1 |
jarsigner -keystore .keystore rfa.jar "Vingrad" |
Ключ -keystore (как Вы наверняка догадались) используется для указания, из какого хранилища брать ключи подписи. Далее следует имя JAR-архива и потом алиас — кто подписывает данный JAR.
У вас будет запрошен пароль (Вы его должны были запомнить) после чего утилита обработает Ваш архив. Если никаких сообщений об ошибках не было Вы может посмотреть содержимое JAr-файла и обнаружить, что в директории META-INF находится файл vingrad.sf. Это как раз подпись.
И теперь мы можем еще раз запустить наш аплет. Как и в прошлый раз
1 |
appletviewer ReadFileApplet.htm |
Нажимаем и … опять ничего не работает. Все верно. мы должны также указать в политике безопасности, что мы можем доверять аплетам, которые подписал «Vingrad».
Для этого надо сделать две вещи:
1. Указать JAVA_HOME. Указать его лучше всего на каталог с SDK
2. И в файл $JAVA_HOME\jre\lib\security\java.policy добавить следующие строки:
1 2 3 4 |
keystore "file:E:/TEMP/TEST/JAR/.keystore"; grant { permission java.io.FilePermission "C:/AUTOEXEC.BAT", "read", signedBy "Vingrad"; } |
И вот теперь мы можем попробовать еще раз
1 |
appletviewer ReadFileApplet.htm |
На этот раз должно все сработать (если Вы ничего не перепутали)
А теперь давайте запустим наш аплет в настоящем броузер. Я использовал IE 6 с установленной JAVA-машиной от Sun. В этом случае при загрузке апплета броузер задаст Вам вопрос — доверяете ли вы данной подписи.
У Вас есть выбор — Yes, No, Always (Да, Нет, Всегда).
Если Вы ответите «ДА», то аплет сможет прочитать файл. Но если Вы захотите повторно загрузить этот
аплет, Вас опять спросят о доверии. Если «НЕТ — то аплет не сможет прочитать файл. Если же Вы ответите «ВСЕГДА», то после этого сколько бы Вы не загружали страничку, ничего Вас спрашивать не будут. Сделайте так. Убедились ?
Но если Вы захотите отменить доверие, что делать ? Вы можете удалить все изменения из файла java.policy и это не поможет. Так где собака зарыта ?
Запустите «Панель управления» и там Вы увидите пункт «Java Plug-In». Давайте запустим. Вы увидите несколько закладок. Из них нас интересует одна — «Sertificates». И там, о чудо, там то, что нам надо — там появился наш сертификат, который говорит о том, что доверять можно. Если Вы удалите его, то следующая загрузка странички породит опять вопрос о доверии.
Небольшое дополнение насчет файла java.policy. Этот файл нужен, чтобы пользователю не выводилось предупреждений.
Т.е. если он есть, и в нем прописан данный производитель ПО, то пользователю не будет выдаваться запросов и предупреждений, апплет сразу получит права прописанные в policy файле.
Если же файл отсутствует или такого производителя ПО там нет, то пользователю будет выдан запрос, доверять ли данному производителю ПО или нет. Если пользователь ответи да, то апплет получит все разрешения.
В общем-то и все. Все Ваши комментарии и замечания будут приняты с благодарностью.