Криптографические методы защиты в языках программирования
Основные проблемы и способы их решения
Классификация криптографических алгоритмов
Работа с ключом: чтение из файла и преобразование в PrivateKey
Проверка подлинности (верификация)
Асимметричная криптография в Perl
Пример использования цифровой подписи
Универсальные криптографические интерфейсы
Использование криптозащиты в других языках
Основные проблемы и способы их решения
аше время часто называют переходным от индустриальной цивилизации к цивилизации преимущественно информационной. Вследствие этого роль накопленных и соответствующим образом обработанных знаний постоянно растет. Появление и стремительное развитие компьютерных сетей обеспечило эффективные способы передачи данных и быстрый доступ к информации как для отдельных личностей, так и для крупных организаций. Однако известно, что локальные и глобальные компьютерные сети (впрочем, как и другие способы передачи информации) могут представлять угрозу для безопасности данных, особенно при отсутствии адекватных мер защиты от несанкционированного доступа.
По мере становления информационного общества средства защиты превращаются в один из основных инструментов, поскольку они обеспечивают доверие, конфиденциальность, секретность, авторизацию, корпоративную безопасность, возможность осуществления электронных платежей и бесчисленное множество других важных атрибутов современной жизни. В связи с этим наличие встроенных механизмов защиты информации и эффективность их работы в прикладных системах стали определяющими факторами при выборе потребителями оптимального решения, поэтому разработчики программных средств уделяют этим вопросам особое внимание.
Надлежащий уровень защиты может быть обеспечен с помощью криптографических методов. Математическая криптография возникла как наука о шифровании и о криптосистемах. В классической модели системы секретной связи имеются два участника, которым необходимо передать секретную (конфиденциальную) информацию, не предназначенную для третьих лиц. Обеспечение конфиденциальности, защиты секретной информации от внешнего противника является одной из главных задач криптографии.
К защите информации можно подходить по-разному. Во-первых, можно попытаться создать абсолютно надежный и недоступный другим канал связи. К сожалению, достичь этого крайне сложно, по крайней мере на современном уровне развития науки и техники, поскольку существующие методы и средства передачи информации одновременно дают возможность несанкционированного доступа к ней. Во-вторых, можно использовать общедоступные каналы связи и при этом скрыть сам факт передачи какой-либо информации. Этим направлением занимается стеганография, но применяемые здесь методы не могут гарантировать должного уровня конфиденциальности. В-третьих, можно использовать общедоступный канал связи, но передавать данные в преобразованном виде, чтобы восстановить их мог лишь адресат. Разработкой методов преобразования информации, обеспечивающей ее шифрование, и занимается криптография.
Со времени своего возникновения сфера криптографии расширилась и видоизменилась. В качестве иллюстрации рассмотрим следующий пример. Допустим, клиент банка намерен переслать деньги со своего счета на счет какой-либо организации. При этом не вся передаваемая информация является конфиденциальной. Действительно, необходимо переслать лишь банковские реквизиты, которые общеизвестны и общедоступны. Однако банку важно убедиться, что деньги хочет перевести именно их владелец, а не злоумышленник. Клиент же заинтересован в том, чтобы сумма не была изменена и чтобы никто не смог ни переслать деньги от его имени, ни изменить информацию о получателе денег.
Любая современная криптосистема работает по определенной методологии (процедуре) и использует следующие компоненты:
- алгоритм шифрования (один или более), который можно выразить в виде математических формул;
- ключи, используемые указанными алгоритмами шифрования;
- система управления ключами;
- незашифрованный (открытый) текст;
- зашифрованный текст (шифротекст).
Пример схемы методологии шифрования с использованием ключей представлен на рис. 1.
Классификация криптографических алгоритмов
уществует два вида методологии с использованием ключей: симметричная с применением секретного ключа и асимметричная — с открытым ключом. Каждая методология использует собственные процедуры, способы распределения и типы ключей, алгоритмы шифрования и расшифровки.
При симметричной (symmetric) методологии с секретным ключом используется один ключ, с помощью которого производится как шифрование, так и расшифровка посредством одного и того же алгоритма симметричного шифрования. Этот ключ передается двум участникам взаимодействия до передачи зашифрованных данных при соблюдении надлежащих мер безопасности. К достоинствам данной системы можно отнести сравнительно большое быстродействие при шифровании и расшифровке передаваемых сообщений, а к недостаткам то, что безопасно распространять секретные ключи довольно трудно.
Пример использования симметричной методологии сеть банкоматов ATM. Эти системы являются оригинальными разработками владеющих ими банков и не продаются сторонним лицам.
При асимметричной (asymmetric) методологии с открытым ключом используются два взаимосвязанных ключа, один из которых является секретным, а другой публикуется в открытых источниках. Данные, зашифрованные одним ключом, могут быть расшифрованы только другим ключом. Главный недостаток необходимость использования очень больших по размеру ключей для обеспечения безопасности, что негативно отражается на скорости работы алгоритмов шифрования.
Часто обе методологии комбинируются. Например, генерируется симметричный (секретный) ключ, который передается с помощью алгоритмов асимметричной методологии.
К самым распространенным алгоритмам симметричной методологии можно отнести DES (Data Encryption Standard), 3-DES, RC2, RC4 и RC5. Примеры асимметричной RSA и ECC. И отдельную позицию занимает один из наиболее популярных алгоритмов цифровой подписи DSA (Digital Signature Algorithm).
Важность сохранения целостности или конфиденциальности информации была очевидна во все времена, но особенно актуальным это стало в связи с развитием информационных технологий, в частности сети Интернет, обеспечивающей удобный и оперативный способ связи. Использование же специальных средств гарантирует необходимый уровень конфиденциальности, причем пользователю компьютера нередко приходится встречаться с такими сложнейшими алгоритмами, как RSA или DSA. В результате уже ни у кого не вызывает удивления использование цифровой подписи или даже шифрование писем электронной почты (рис. 2).
Наличие встроенных механизмов защиты информации в прикладных системах все чаще становится определяющим фактором при их выборе потребителями, о чем хорошо знают все разработчики программных средств. Однако работы по созданию и тестированию криптографической защиты требуют существенных финансовых затрат. Кроме того, необходимы квалифицированные сотрудники, в частности криптографы и программисты с математическим образованием. Все это в значительной степени определяет качество разработки и успех реализации универсальных интерфейсов.
Многие фирмы, в том числе крупнейшие системные интеграторы, применяя криптографическую защиту в своих прикладных системах, пошли по пути реализации универсальных интерфейсов. В их задачи входит предоставление приложению широкого набора возможностей по вызову криптографических сервисов, что обеспечивает гибкость системы и определенную ее независимость от алгоритмов. В результате такого подхода разработчикам программного обеспечения нет необходимости задумываться над тем, какие именно алгоритмы криптографической защиты будут реализованы в конечном продукте используются лишь интерфейсы вызовов функций защиты, созданных сторонними производителями. Примером может служить фирма Sun Microsystems, предлагающая разработчикам программного обеспечения язык Java с широким набором интерфейсов, реализующих основные криптографические алгоритмы и протоколы.
Криптография в Java
зык Java создан сравнительно недавно и имеет множество достоинств и немало недостатков. Часто эти достоинства сводят только к возможности создания машинно-независимых приложений, но существуют и другие, возможно даже более важные в условиях стремительного развития информационного общества. Речь идет, в частности, о сетевой направленности при разработке языка.
В 1993 году компания Sun обратила внимание на рост популярности Интернета и начала дорабатывать Java таким образом, чтобы написанные программы можно было запускать из Web-браузеров (аплеты). Также в язык были встроены расширенные возможности создания приложений типа «клиент-сервер». В связи с явной сетевой направленностью языка Java необходимо было уделить должное внимание средствам защиты. В первую очередь это касалось пересылки важных данных, например между клиентом и сервером, а также запуска программ или аплетов. Такие средства были разработаны и встроены в набор стандартных библиотек (JDK security API).
Необходимость защиты может быть обусловлена желанием пользователя-получателя иметь возможность верификации, что дает определенные гарантии подлинности документа или кода. В качестве подписываемого объекта могут выступать аплеты, которые широко распространены в Интернете. В результате у получателя появляется уверенность, что информация получена именно от нужного отправителя и что она не была изменена в процессе пересылки. Для обеспечения такого рода безопасности служат цифровые подписи и сертификаты.
Алгоритм DSA
Основная идея цифровой подписи (digital signature) заключается в следующем. Допустим, отправитель хочет послать получателю некоторые данные. Он подписывает документ или код посредством специального закрытого ключа (private key), который генерируется с помощью утилиты keytool или средствами API. В данном случае слово «подписывает» означает, что генерируется специальная цифровая подпись с помощью утилиты jarsigner или средствами API.
Диаграмма, иллюстрирующая прохождение через все этапы подписи jar-архива (работа отправителя), представлена на рис. 3. Следует отметить, что в jar-файле могут быть произвольные данные, например программа, картинка или документ Word.
Диаграмма, представляющая работу получателя jar-архива, дана на рис. 4.
В процессе генерации закрытого ключа создается и так называемый открытый ключ (public key), который соответствует закрытому.
Получателю отправляются следующие данные:
- исходный документ или код;
- цифровая подпись (отдельно либо в составе jar-файла);
- открытый ключ.
Приняв все три компонента, получатель с помощью открытого ключа определяет подлинность подписи и целостность документа. Защищенность данного метода заключается в том, что для подделки или взлома необходимо сгенерировать закрытый ключ. При этом для данной задачи не существует «быстрого» алгоритма при условии, что длина ключей достаточно велика.
Правда, указанный простой метод имеет свои недостатки. Дело в том, что получатель в предложенной схеме заведомо предполагает подлинность и целостность открытого ключа. Однако злоумышленник мог изменить или подменить открытый ключ, а следовательно, сгенерировать фальшивую подпись и подменить документ. Таким образом, в этом случае необходим механизм, удостоверяющий подлинность открытого ключа.
Примером могут служить сертификаты (certificate), которые поставляются сторонними организациями и содержат в себе открытый ключ и некоторую дополнительную информацию. В качестве последней выступают сведения об отправителе, данные о поставщике сертификата и цифровая подпись все это дает определенную гарантию того, что открытый ключ принадлежит отправителю.
Если при этом имеет место доверие составителю сертификата, проблему можно считать решенной. В противном случае необходимо обратиться к еще одной сторонней организации и запросить новый сертификат, удостоверяющий подлинность уже имеющегося сертификата. И так до тех пор, пока пользователь не найдет организацию, которой он может полностью доверять. Альтернативой здесь может быть использование самоподписанных сертификатов (CSR).
Следует отметить, что для доказательства сложности взлома данного метода потребовались колоссальные математические исследования.
Рассмотрим возможность использования Java Security для генерации (рис. 5) и верификации (рис. 6) цифровой подписи.
Работа отправителя
Генерация ключей
Для генерации ключей программист, не вникая в математические формулы и особенности их реализации, может использовать уже готовые алгоритмы и методы криптографии. Они предоставляются определенными организациями, так называемыми провайдерами (provider). По умолчанию встроенные средства Java поставляет провайдер SUN. Таким образом, единственное, что необходимо сделать это указать собственно алгоритм и провайдера.
В первую очередь нужно сгенерировать пару ключей public key и private key, для чего используется класс KeyPairGenerator. С целью получения конкретного объекта этого класса необходимо вызвать static factory метод getInstance(). В качестве аргументов передаются строки с указанием алгоритма и провайдера. Например, для использования DSA (Digital Signature Algorithm) и провайдера SUN необходимо писать:
KeyPairGenerator keyGen = KeyPairGenerator.getInstance (“DSA”, “SUN”);
Поскольку большинство криптографических алгоритмов являются вероятностными, необходимо создать вероятностный источник объект класса SecureRandom. При этом существует возможность использовать разные методы, например SHA1PRNG (pseudo-random-number generation algorithm):
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.
Microsoft CryptoAPI
Порядок взаимодействия приложений с криптографическими модулями операционной системы регламентирует документ, который называется Microsoft Cryptographic Application Programming Interface (MS CryptoAPI). Функции, описанные в нем, поддерживаются Windows 9x и Windows NT/2000/XP. В последних ОС функции CryptoAPI содержатся в модулях crypt32.dll и advapi32.dll, но они не реализуют криптографических алгоритмов, а обращаются к другим модулям, называемым Cryptographic Service Providers (CSP). Одновременно в операционной системе можно установить несколько CSP. При первом обращении к CryptoAPI прикладная программа выбирает, с каким именно модулем CSP она будет работать в зависимости от того, какие криптографические алгоритмы ей необходимы (рис. 7). Следует отметить, что система по организации похожа на ту, что используется в Java.
CryptoAPI позволяет шифровать данные, подписывать документы цифровой подписью и многое другое. Существуют и встроенные средства, например Microsoft Base Cryptographic Provider. Имеется возможность использовать CryptoAPI в таких программах разработки, как Visual Studio, то есть автоматически осуществляется поддержка таких языков, как Visual C++, Visual Basic, Visual FoxPro и др. С развитием компанией Microsoft языковой платформы .NET большинство языков программирования, включая набирающий популярность язык C#, поддерживают криптографические методы защиты.
Примером функции генерации ключей может быть CryptGenKey(), а шифрования и дешифрования CryptEncrypt() и CryptDecrypt() и т.д.
Использование криптозащиты в других языках
сли в языке нет встроенных средств криптографической защиты, то существуют два варианта действий. Во-первых, можно попытаться создать все с нуля. Однако, к сожалению, чаще всего это невозможно, так как связано с реализацией сравнительно сложных алгоритмов. Во-вторых, можно использовать объектные модули, созданные на основе трансляторов с разных языков программирования, что, несомненно, более перспективно.
Допустим, имеется ряд языков, на которых уже реализованы нужные алгоритмы. Трансляторами с этих языков обеспечивается получение объектных кодов, которые можно использовать при разработке приложения на другом языке. Естественно, это не всегда легко реализовать, но такие языки, как, например, Алгол, Фортран, PL1, благодаря схожему синтаксису языковых конструкций и реализации трансляторов, как правило, в этом смысле вполне совместимы.
Пример такой работы представлен на рис. 8.
Рассматривая возможность применения указанного способа, необходимо отметить, что в случае возникновения трудностей при стыковке модулей, созданных на разных языках программирования, обычно имеется возможность использовать для этой цели ассемблер. При этом соответствующие структуры ассемблера могут применяться как для промежуточной передачи параметров, так и для осуществления вызова объектных модулей.
Заключение
авершая данный обзор, хотелось бы еще раз подчеркнуть, что каждый из описанных нами способов реализации криптографических средств защиты информации обладает как достоинствами, так и недостатками. Выбор определяется поставленными задачами с учетом особенностей реализации, эксплуатации и финансовых возможностей. При этом необходимо принимать во внимание используемые аппаратные средства, необходимую степень защиты информации и т.д.
Как показывает практика, криптографические методы защиты действительно обеспечивают безопасность на достаточно высоком уровне. Несомненно, что данное направление будет быстро развиваться с появлением новых коммуникационных аппаратно-программных средств. Большинство современных компаний стараются разработать универсальные криптографические интерфейсы и избавить разработчика программного обеспечения от самостоятельных реализаций сложных алгоритмов. И JDK security API, и CryptoAPI, и встроенные средства .NET предоставляют богатый набор средств шифрования, позволяющих организовать собственную систему защиты данных. Однако надо отметить, что на пути реализации эффективной защиты информации существует множество технологических трудностей. Поскольку соответствующие аппаратно-программные средства стремительно развиваются, это позволяет рассчитывать на появление новых решений, которые будут лишены существующих недостатков.
Литература:
- Введение в криптографию / Под общ. ред. В.В.Ященко. М.:МЦНМО, «ЧеРо», 1998.
- А.Никитин. Универсальные криптографические интерфейсы // Защита информации, Конфидент, № 5, 1997.
- М.Могран. Java 2. Руководство разработчика. Пер. с англ.: Уч. пос. М.: «Вильямс», 2000.
- Vipul Ved Prakash, Benjamin Trott. Asymmetric Cryptography in Perl. O’Reilly, 2001.
- R.Coleridge. The Cryptography API, or How to Keep a Secret. MSDN, 1996.
- D.Esposito. Supporting CryptoAPI in Real-World Applications. MSDN, 1997.
- http://java.sun.com.
- S.K.Parmar. An introduction to security. Fred Cohen &Associates, 2000.
- R.L/Rivest, A.Shamir and L.Adleman. A method for obtaining digital signatures and public key cryptosystems. // Commun. ACM, vol.21, 1978.
- W.Diffie and M.E.Hellman. New directions in cryptograpgy. // IEEE Trans.Inf.Theory, vol.IT-22, № 6, Nov. 1976.
- A.Menezes, P.van Oorschot, S.Vanstone. Handbook of applied cryptography. CRC Press, 1996.