Signature sig = Signature.getInstance("SHA1withDSA", "SUN");
sig.initVerify(pubKey);
Во время чтения необходимо применять метод update() объекта sig, аналогично случаю создания подписи.
Проверка подлинности (верификация).
Завершающим этапом работы получателя является собственно получение ответа на вопрос о правдивости подписи и данных. С помощью метода verify() объекта класса Signature можно получить результатом boolean:
boolean verifies = sig.verify(sigToVerify);
Значение будет true, если данная подпись (sigToVerify) действительная подпись для данных, созданная с использованием открытого ключа (pubKey).
Следует отметить, что первый этап, связанный с работой отправителя, требует некоторого времени для генерации необходимых для отправки данных. Для компьютера класса Intel Pentium III с частотой 733 МГц время генерации составляет приблизительно 10 секунд. Кстати, время, затрачиваемое для верификации на порядок меньше.
Кроме рассмотренного DSA, предоставляются и многие другие средства криптографической защиты, как RSA, DES и другие. Их использование подобно представленному DSA.
2.2 Реализация алгоритма DES для шифрования и расшифровки файла
Симметрическое шифрование - способ шифрования, в котором для (за)шифрования и расшифрования применяется один и тот же криптографический ключ. Рассмотрим реализацию симметрического шифрования в java на примере алгоритма DES. В первую очередь нам понадобится класс javax.crypto.Cipher, который реализует базовые функции популярных криптографических алгоритмов шифрования. Для создания экземпляра такого класса используется статистический метод Cipher.getInstance , который в качестве параметра получает имя криптографического алгоритма шифрования. В нашем случае:
Cipherchr= Cipher.getInstance("DES");
Следующим шагом будет инициализация экземпляра класса и указание каком режиме он будет работать: в режиме шифрования chr.init(Cipher.ENCRYPT_MODE, key); - , или расщифрования –
chr.init(Cipher.DECRYPT_MODE, key);
Как видно, появился новый неизвесный параметр: key - это 56 битный ключ алгоритма DES. Данный параметр имеет тип javax.crypto.SecretKey и может быть создан с помощью класса:
javax.crypto.KeyGenerator. SecretKey key = KeyGenerator.getInstance("DES").generateKey();
Шифрование или расшифрование выполняет функция doFinal класса Cipher, которая на входе получает масив байт и возвращает также масив байт, но уже соответственно преобразованных. Что именно (шифрование или расшифрование) будет выполнять функция зависит от того что было указанно в первом параметре функции инициализации init(). Итак из всего выше сказанного можно скомпоновать небольшой класс. Класс по работе скриптографическим алгоритмом шифрования DES. К классу прилагается функция main, для того что-бы проверить правильность работы созданных функций.
2.3 Запись ключей в класс с помощью сериализации
Для того, чтобы объект был сериализуемым, класс этого объекта должен реализовывать интерфейс java.io.Serializable.
Интерфейс java.io.Serializable не содержит методов и является маркером, который говорит механизму сериализации о том, что объект, реализующий данный интерфейс, может быть сериализован.
Теперь, когда у нас уже есть класс, реализующий интерфейс java.io.Serializable, следующим шагом станет написание алгоритма, ответственного за сериализацию экземпляра класса SecretKey.
2.4 Стандартные диалоговые окна открытия и сохранения файла
Swing содержит готовое окно для выбора файла (полезное, например, для программирования пункта меню Файл --> Открыть). Объект класса JFileChooser создается простым конструктором без параметров, после чего может выводиться на экран методом showOpenDialog(). Этот метод возвращает результат действий пользователя по выбору файла, который сравнивается с одной из следующих констант:
APPROVE_OPTION — выбор файла прошел успешно. Теперь можно методом getFile() получить выбранный файл.
CANCEL_OPTION — пользователь отменил выбор файла, щелкнув на кнопке Cancel.
ERROR_OPTION — при выборе файла произошла ошибка, либо пользователь закрыл диалоговое окно крестиком.
Метод showSaveDialog() отображает то же самое окно, но теперь оно работает в режиме сохранения. Пользователь выбирает директорию для сохранения файла и может ввести его имя. Метод возвращает результат того же типа, что и showOpenDialog(). Если выбор пути для сохранения прошел успешно, вызов метода getFile() вернут путь, куда пользователь желает сохранить файл.
Следует иметь в виду, что сам класс JFileChooser ничего не открывает и не сохраняет. Он только возвращает путь к выбранному пользователем файлу. А открыть его или сохранить файл в заданном месте должна уже сама программа.
Метод setDialogTitle(String title) позволяет задать окну заголовок.
3.1 Шифрование файла
Для шифрования файла нажать на кнопку «Зкодировать файл» главного меню программы (Рис. 3.1), после чего откроется стандартное диалоговое окно для открытия файла (Рис. 3.2), в котором нужно выбрать файл для шифрования. После этого откроется стандартное диалоговое окно для сохранения файлов (Рис. 3.3), в котором необходимо выбрать место расположения и названия закодированного файла. Затем появляется еще одно диалоговое окно сохранения файла с требованьем указать ему адрес сохранения файла ключей. После чего в случае успешной шифровки файла по алгоритму DES выдается сообщение типа MessageBox с уведомлением о успешном кодировании файла(Рис 3.4).
Рисунок 3.1 – Главное окно программы
Рисунок 3.2 – Стандартное диалоговое окно для открытия файла
Рисунок 3.3 – Стандартное диалоговое окно для сохранения файла
Рисунок 3.4 – Стандартное окно сообщения
3.2 Расшифровка закодированого файла
Для расшифровки закодированного файла необходимо выбрать в главном окне программы (Рис 3.1) пункт меню «расшифровать файл». После чего указать: файл для расшифровки, адрес для сохранения декодированного файла, ключ шифрования. После чего в случае совпадения ключа происходит успешная расшифровка по указанному адресу и появляется сообщения с уведомлением об успешном завершении, или о несоответствии файла ключей.
3.3 Создания цифровой подписи файла
Для создания цифровой подписи файла необходимо в главном меню программы (Рис. 3.1) выбрать пункт меню «Подписать файл». После чего в стандартном диалоговом окне открытия файла указать путь к подписываемому файлу. После чего выводиться сообщение о успешном создании цифровой подписи и в директории с эти файлом создается файл с таким же именем и расширением .sig – это цифровая подпись и с расширением .pubkey – это публичный ключ для проверки цифровой подписи.
3.4 Проверка цифровой подписи файла
Для проверки цифровой подписи файла необходимо в главном меню программы (Рис. 3.1) выбрать пункт меню «Проверить цифровую подпись». После чего необходимо указать путь к проверяемому файлу, путь к файлу с цифровой подписью и файл с публичным ключом. В случае корректного указания всех файлов и неизменности проверяемого файла выдается сообщение, что верификация прошла успешно. Если хотя бы один бит в одном из этих файлов был модифицирован, выдается уведомление о несанкционированном доступе.
Перечень ссылок
1. “Введение в криптографию” / Под общ. ред. В.В.Ященко. — М.:МЦНМО, ”ЧеРо”, 1998. — 272c.
2. А.Никитин, “Универсальные криптографические интерфейсы”, Защита информации, Конфидент, N5, 1997.
3. М.Могран, “Java 2. Руководство разработчика”, Пер. с англ. : Уч. пос. — М.: “Вильямс”, 2000. — 720c. : ил.
4. Vipul Ved Prakash, Benjamin Trott, “Asymmetric Cryptography in Perl”, O'Reilly, 2001.
5. R.Coleridge, “The Cryptography API, or How to Keep a Secret”, MSDN, 1996.
6. D.Esposito, “Supporting CryptoAPI in Real-World Applications”, MSDN, 1997.
7. http://java.org
8. S.K.Parmar, “An introduction to security”, Fred Cohen &Associates, 2000.
9. R.L/Rivest, A.Shamir and L.Adleman, “A method for obtaining digital signatures and public key cryptosystems”. Commun. ACM, vol.21, p. 120-126, 1978.
10. W.Diffie and M.E.Hellman, “New directions in cryptograpgy”, IEEE Trans.Inf.Theory, vol.IT-22, N6, p.644-654, Nov. 1976.
11. A.Menezes, P.van Oorschot, S.Vanstone, “Handbook of applied cryptography”, CRC Press, 1996.
Код класса my_java_sec
public class my_java_sec {
@SuppressWarnings("deprecation")
public static void main(String[] args){
// TODO Auto-generated method stub
FInterfaceForm fif = new FInterfaceForm();
fif.show();
}
}
ПриложениеБ
Кодклассаcoding_files
import java.io.FileInputStream;
import java.io.FileOutputStream;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class CodingFiles {
Cipher ecipher;
Cipher dcipher;
public CodingFiles() {
// TODO Auto-generated constructor stub
}
public SecretKey initCoding()
{
try{
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
ecipher = Cipher.getInstance("DES");
dcipher = Cipher.getInstance("DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
return key;
}
catch(Exception e)
{
}
return null;
}
public void iniCoding(SecretKey key)
{
try{
ecipher = Cipher.getInstance("DES");
dcipher = Cipher.getInstance("DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
}
catch(Exception e)
{
}
}
public boolean fileEncode(String sourse,String result)
{
try{
FileInputStream inFile = new FileInputStream(sourse);
int bytesAvailable = inFile.available();
byte[] bytesReaded = new byte[bytesAvailable];
inFile.read(bytesReaded,0,bytesAvailable);
inFile.close();
byte[] br_enc = ecipher.doFinal(bytesReaded);
FileOutputStream outFile = new FileOutputStream(result);
outFile.write(br_enc);
outFile.close();
return true;
}
catch(Exception e)
{}
return false;
}
public boolean fileDecode(String sourse,String result)
{
try{
FileInputStream enc_inFile = new FileInputStream(sourse);
int enc_bytesAvailable = enc_inFile.available();
byte[] enc_bytesReaded = new byte[enc_bytesAvailable];
enc_inFile.read(enc_bytesReaded,0,enc_bytesAvailable);
enc_inFile.close();
byte[] br_dec =dcipher.doFinal(enc_bytesReaded);
FileOutputStream dec_outFile = new FileOutputStream(result);
dec_outFile.write(br_dec);
dec_outFile.close();
return true;
}
catch(Exception e)
{}
return false;