Криптографические методы защиты в языках программирования

Автор работы: Пользователь скрыл имя, 20 Марта 2013 в 13:24, реферат

Краткое описание

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

Содержание

Основные проблемы и способы их решения
Классификация криптографических алгоритмов
Криптография в Java
Алгоритм DSA
Работа отправителя
Генерация ключей
Создание подписи
Сохранение подписи
Работа получателя
Работа с ключом: чтение из файла и преобразование в PrivateKey
Проверка подлинности (верификация)
Исходные программы
Асимметричная криптография в Perl
Алгоритм RSA
Основные методы работы с RSA
Пример использования цифровой подписи
RSA
DSA
Универсальные криптографические интерфейсы
Microsoft CryptoAPI
Использование криптозащиты в других языках
Заключение

Прикрепленные файлы: 1 файл

Криптографические методы защиты в языках программировани1.doc

— 200.00 Кб (Скачать документ)

SecureRandom random = SecureRandom.getInstance

(“SHA1PRNG”,  “SUN”);

Далее нужно инициализировать объект keyGen, передав ему два параметра  — длину в битах и источник случайности:

keyGen.initialize(1024, random);

Последним этапом является собственно генерация пары ключей (метод generateKeyPair()) и выделение двух отдельных ключей (методы getPrivate() и getPublic()):

KeyPair pair = keyGen.generateKeyPair();

PrivateKey privKey = pair.getPrivate();

PublicKey pubKey = pair.getPublic();


 

Создание подписи

В первую очередь необходимо создать  объект класса Signature, вызвав метод getInstance():

Signature dsa = Signature.getInstance(“SHA1withDSA”, 

“SUN”);

В данном случае используется алгоритм DSA с SHA1 (хэш-функция). Затем идет процесс  инициализации подписи закрытым ключом, полученным ранее:

dsa.initSign(privKey);

После этого необходимо свести подпись  и сами данные. Для этого вызывается метод update(), получаемый в качестве параметра  байтовый массив данных, которые должны быть подписаны.

На последнем этапе генерируется сама подпись, которая представляется в виде байтового массива:

byte[] realSig = dsa.sign();


 

Сохранение подписи

После получения подписи и ключей необходимо сохранить их, например, в файл и отправить адресату вместе с исходными данными. Следует подчеркнуть, что закрытый остается у отправителя, а адресату отсылается только открытый ключ.

Итак, отправитель посылает получателю по электронной почте или через прямое сетевое соединение следующие файлы:

  • открытый ключ (public key);
  • цифровую подпись (digital signature);
  • исходные данные (подписанный документ или код).


 

Работа получателя

Работа с ключом: чтение из файла  и преобразование в PrivateKey

Получатель располагает последовательностью  байтов, представляющих открытый ключ. Необходимо получить байтовый массив (Byte[] encKey), например прочитать эти данные из файла в массив, а затем преобразовать его в объект класса PublicKey. Для этого можно воспользоваться классом KeyFactory, который по спецификации ключа может восстановить объект класса Key (PrivateKey и PublicKey являются потомками класса Key). Следовательно, необходимо получить так называемую спецификацию ключа. Ее можно получить, основываясь на том, какой стандарт использовался при генерации ключа. В данном случае ключ был сгенерирован с помощью провайдера SUN, поэтому он удовлетворяет стандарту X.509.

Генерация спецификации ключа (необходим  пакет java.security.spec.*):

X509EncodedKeySpec pubKeySpec =

new X509EncodedKeySpec(encKey);

Создание объекта класса KeyFactory, соответствующего цифровой подписи и провайдеру SUN:

KeyFactory keyFactory = KeyFactory.getInstance

(“DSA”, “SUN”);

Получение объекта класса PublicKey

PublicKey pubKey =

keyFactory.generatePublic(pubKeySpec);

Работа с подписью: чтение из файла  и Signature

Подпись также необходимо перевести в байтовый массив (Byte[] sigToVerify). Затем нужно создать объект типа Signature, как это делалось ранее.

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.


 

Исходные программы

Ниже представлены тексты уже готовых и работающих программ: GSig.java подписывает данные из файла data, генерирует открытый ключ и подпись, записывая их соответственно в файлы signature и publickey; VSig.java читает данные из файлов signature, publickey и data и выводит на экран сообщение о подлинности подписи (о соответствии подписи данным).

GSig.java

/* Генерация DSA-подписи */

import java.io.*;

import java.security.*;

class GSig

//сохранение байтового массива  в файл

public static void saveToFile (byte[] info,

String filename)

{

try

{

FileOutputStream fos = new FileOutputStream

(filename);

fos.write(info);

fos.close();

}

catch (Exception e)

{

System.err.println(“Caught exception “ +

e.toString());

}

}// saveToFile ()

 

public static void main(String args[])

{

try

{

/* Генерация ключей */

KeyPairGenerator keyGen =

KeyPairGenerator.getInstance(“DSA”, “SUN”);

SecureRandom random =

SecureRandom.getInstance(“SHA1PRNG”, “SUN”); 

keyGen.initialize(1024, random); 

KeyPair pair = keyGen.generateKeyPair();

PrivateKey priv = pair.getPrivate();

PublicKey pub = pair.getPublic(); 

/* Создание объекта класса Signature */ 

Signature dsa =

Signature.getInstance(“SHA1withDSA”, “SUN”);

/* Инициализация частным ключом */

dsa.initSign(priv); 

/* Чтение данных из файла “data”.  Вызов метода update() */ 

FileInputStream fis = new FileInputStream(“data”);

BufferedInputStream bufin =

new BufferedInputStream(fis);

byte[] buffer = new byte[1024];

int len;

while (bufin.available() != 0)

{

len = bufin.read(buffer);

dsa.update(buffer, 0, len);

}

bufin.close(); 

/* Генерация подписи */

byte[] realSig = dsa.sign(); 

/* Сохранение подписи в файл  “signature” */

saveToFile (realSig,”signature”); 

/* Сохранение открытого ключа  в файл “pubkey” */

byte[] key = pub.getEncoded();

saveToFile (key,”pubkey”);

}  

catch (Exception e)

{

System.err.println(“Caught exception “ +

e.toString());

}// main()

}// class GSig

VSig.java

/* Верификация DSA-подписи */

import java.io.*;

import java.security.*;

import java.security.spec.*;

class VSig

//чтение из файла в байтовый массив

public static byte[] readFromFile (String fileName)

{

byte[] info;

try

{

FileInputStream fis =

new FileInputStream(fileName);

info = new byte[fis.available()];

fis.read(info);

fis.close();

}

catch (Exception e)

{

System.err.println(“Caught exception “ +

e.toString());

info = new byte[0];

}

return(info);

}// copyFromFile () 

public static void main(String args[])

{

try

{

/* Получение encoded public key из файла  “pubkey” */

byte[] encKey = readFromFile(“pubkey”);

 

/* Создание спецификации ключа  */

X509EncodedKeySpec pubKeySpec =

new X509EncodedKeySpec(encKey); 

.* Создание объектов Лунафсещкн  и ЗгидшсЛун*.

KeyFactory keyFactory = KeyFactory.getInstance

(“DSA”, “SUN”);

PublicKey pubKey = keyFactory.generatePublic

(pubKeySpec); 

/* Чтение подписи из файла “signature” */

byte[] sigToVerify = readFromFile(“signature”); 

/* Создание объекта класса Signature и инициализация с помощью  открытого ключа    */

Signature sig = Signature.getInstance

(“SHA1withDSA”, “SUN”);

sig.initVerify(pubKey); 

/* Чтение данных из файла “data” и вызов метода update() */

FileInputStream datafis = new FileInputStream

(“data”);

BufferedInputStream bufin =

new BufferedInputStream(datafis);

byte[] buffer = new byte[1024];

int len;

while (bufin.available() != 0)

{

len = bufin.read(buffer);

sig.update(buffer, 0, len);

}

bufin.close(); 

/* Верификация */

boolean verifies = sig.verify(sigToVerify); 

System.out.println(“Signature verifies: “ + verifies);

catch (Exception e)

{

System.err.println(“Caught exception “ +

e.toString());

}

}// main()

}// class VSig


 

Асимметричная криптография в Perl

овольно популярный Интернет-направленный язык Perl также имеет встроенные средства обеспечения защиты. Для примера  рассмотрим использование криптографического алгоритма шифрования RSA.


 

Алгоритм RSA

Задача, которую решает RSA, — это  передача секретной информации таким  образом, чтобы прочитать ее смог лишь адресат.

Потенциальным получателем шифрованного сообщения выполняются следующие  действия:

  • генерируются два больших простых числа (например, 1024 бит, 308 знаков)  — p и q;
  • подсчитывается их произведение n = pq;
  • выбирается случайное число e, которое взаимно просто с числом (p-1)(q-1), а также не превосходит его;
  • подсчитывается величина d такая, что ed = 1 mod (p-1)(q-1);
  • пара (n, e) становится открытым ключом (public key), а d — закрытым ключом (private key).

Открытый ключ публикуется в  открытых источниках, например пересылается по электронной почте.

Отправителю шифрованного сообщения  для работы необходимо выполнить  следующие действия:

  • получить открытый ключ;
  • создать сообщение в числовом виде m, не превосходящем n;
  • подсчитать величину c = (me) mod n.

Величина с — это и есть зашифрованное сообщение, которое отправляется создателю открытого ключа.

Получатель закодированного сообщения  вычисляет m = (cd) mod n и получает сообщение в расшифрованном виде.

Стойкость алгоритма RSA обеспечивается благодаря тому, что злоумышленнику необходимо получить число d, которое можно вычислить только в случае, если удастся факторизовать число n. Однако на данный момент не существует быстрых алгоритмов, решающих задачу факторизации больших чисел.


 

Основные методы работы с RSA

В языке Perl вся криптография поставляется через модули CPAN. Реализация RSA находится  в пакете Crypt::RSA.

Генерация 2048-битовых ключей:

$rsa = new Crypt::RSA;

$public, $private) = $rsa->keygen( Size => 2048 )

Открытый ключ публикуется. Шифрование данных (строка $message) с использованием открытого ключа:

my $c = $rsa->encrypt( Message => $message,

Key => $public );

В результате получается шифрованное  сообщение $c, которое отправляется обратно адресату. Получатель использует для расшифровки ранее сгенерированный  закрытый ключ $private,:

$message = $rsa->decrypt( Ciphertext => $c,

Key => $private );

Кроме представленных строк исходного текста на языке Perl, отметим некоторые дополнительные особенности пакета. Для отправки защищенных сообщений информация должна быть представлена в виде одного или нескольких чисел, значения которых не превосходят n. При этом каждому сообщению соответствует определенное число, и наоборот. Средства языка Perl позволяют дробить сообщение на последовательность таких чисел, а также в дальнейшем соединять их обратно в текст.

К сожалению, в системе RSA есть одно слабое место, снижающее степень защищенности. Если злоумышленник может каким-либо образом заставить отправителя закодировать уже известное ему сообщение, то величины p и q могут быть подсчитаны без факторизации n. Однако с этим можно успешно бороться, перегружая исходное сообщение так называемым мусором (padding), и для этой операции был разработан стандарт PKCS #1. Кроме того, Crypt::RSA реализует не только PKCS #1, но и более современный OAEP, который использует padding по умолчанию. При использовании PKCS #1 необходимо передать соответствующий параметр конструктору:

$rsa = new Crypt::RSA ( ES => ‘PKCS1v15 )


 

Пример использования цифровой подписи

RSA

Проверка подлинности и целостности  сообщения обычно решается с помощью DSA-алгоритма, однако можно использовать и пакет Crypt::RSA.

В первую очередь необходимо сгенерировать  ключи, причем обычно ключи уже готовы и хранятся в файле под паролем. Для создания $private используется конструктор Crypt::RSA::Key::Private(), которому в качестве параметров передается имя файла и пароль.

$private = new Crypt::RSA::Key::Private(

Filename => “keys/имя_файла.private”, 

Password => ‘пароль’ 

);

Подпись осуществляется с помощью $rsa->sign(). При этом в качестве параметров выступают сообщение и закрытый ключ:

$rsa = new Crypt::RSA;

$signature = $rsa->sign ( Message => $message,

Key => $private );

Сообщение $message и подпись $signature отправляются адресату, который, используя открытый ключ, получает подтверждение подлинности подписи:

$public = new Crypt::RSA::Key::Public(

Filename => “keys/имя_файла.public”,);

$rsa->verify( Message => $message,

Signature => $signature,

Key => $public )

|| die “Подпись поддельная!\n”;


 

DSA

DSA реализуется в пакете Crypt::DSA. Использование  DSA аналогично RSA-подписи, но здесь есть и свои особенности.

Сначала генерируется DSA-ключ:

use Crypt::DSA;

$dsa = Crypt::DSA->new;

$key = $dsa->keygen( Size => 512 );

Подпись осуществляется стандартным  образом:

$sig = $dsa->sign( Message => $message, Key => $key );

Получателю посылаются сообщение, подпись и открытый ключ. В процессе верификации (при этом используется открытый ключ $pub_key) подпись либо принимается ($valid=true), либо отвергается ($valid=false):

$valid = $dsa->verify( Signature => $sig,

$message,

Key => $pub_key );

В заключение необходимо подчеркнуть, что реализованные алгоритмы  криптографической защиты в пакетах  для языка Perl могут широко использоваться в Интернет-ориентированных проектах.


 

Универсальные криптографические  интерфейсы

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

Первоначально многие интерфейсы возникали  в качестве внутрикорпоративных  стандартов — таким образом появились CryptoAPI (Microsoft), Cryptoki (RSA Data Security), GCS-API (X/Open). Интерфейс CpyptoAPI ориентирован на использование в ОС Windows NT, в то время как остальные не имеют четких ограничений, хотя чаще используются в ОС Unix. Международная организация по стандартизации IETF (Internet Engineering Task Force) попыталась создать единый универсальный стандарт, который был назван GSS-API.

Информация о работе Криптографические методы защиты в языках программирования