Используем средства библиотеки OpenSSL для криптографической защиты данных. Часть 2::Журнал СА 5.2006
www.samag.ru
     
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
Журнал "Системный администратор"
Журнал «БИТ»
Подписка
Архив номеров
Где купить
Наука и технологии
Авторам
Рекламодателям
Контакты
   

  Опросы
  Статьи

Дата-центры  

Дата-центры: есть ли опасность утечки данных?

Российские компании уже несколько лет испытывают дефицит вычислительных мощностей. Рост числа проектов,

 Читать далее...

Событие  

В банке рассола ждет сисадмина с полей фрактал-кукумбер

Читайте впечатления о слете ДСА 2024, рассказанные волонтером и участником слета

 Читать далее...

Организация бесперебойной работы  

Бесперебойная работа ИТ-инфраструктуры в режиме 24/7 Как обеспечить ее в нынешних условиях?

Год назад ИТ-компания «Крок» провела исследование «Ключевые тренды сервисного рынка 2023». Результаты

 Читать далее...

Книжная полка  

Читайте и познавайте мир технологий!

Издательство «БХВ» продолжает радовать выпуском интересных и полезных, к тому же прекрасно

 Читать далее...

СУБД PostgreSQL  

СУБД Postgres Pro

Сертификация по новым требованиям ФСТЭК и роль администратора без доступа к данным

 Читать далее...

Критическая инфраструктура  

КИИ для оператора связи. Готовы ли компании к повышению уровня кибербезопасности?

Похоже, что провайдеры и операторы связи начали забывать о требованиях законодательства

 Читать далее...

Архитектура ПО  

Архитектурные метрики. Качество архитектуры и способность системы к эволюционированию

Обычно соответствие программного продукта требованиям мы проверяем через скоуп вполне себе понятных

 Читать далее...

Как хорошо вы это знаете  

Что вам известно о разработках компании ARinteg?

Компания ARinteg (ООО «АРинтег») – системный интегратор на российском рынке ИБ –

 Читать далее...

Графические редакторы  

Рисование абстрактных гор в стиле Paper Cut

Векторный графический редактор Inkscape – яркий представитель той прослойки open source, с

 Читать далее...

День сисадмина  

Учите матчасть! Или как стать системным администратором

Лето – время не только отпусков, но и хорошая возможность определиться с профессией

 Читать далее...

День сисадмина  

Живой айтишник – это всегда движение. Остановка смерти подобна

Наши авторы рассказывают о своем опыте и дают советы начинающим системным администраторам.

 Читать далее...

Виртуализация  

Рынок решений для виртуализации

По данным «Обзора российского рынка инфраструктурного ПО и перспектив его развития», сделанного

 Читать далее...

Книжная полка  

Как стать креативным и востребованным

Издательский дом «Питер» предлагает новинки компьютерной литературы, а также книги по бизнесу

 Читать далее...

Книжная полка  

От создания сайтов до разработки и реализации API

В издательстве «БХВ» недавно вышли книги, которые будут интересны системным администраторам, создателям

 Читать далее...

1001 и 1 книга  
19.03.2018г.
Просмотров: 6227
Комментарии: 0
Машинное обучение с использованием библиотеки Н2О

 Читать далее...

12.03.2018г.
Просмотров: 6933
Комментарии: 0
Особенности киберпреступлений в России: инструменты нападения и защита информации

 Читать далее...

12.03.2018г.
Просмотров: 4215
Комментарии: 0
Глубокое обучение с точки зрения практика

 Читать далее...

12.03.2018г.
Просмотров: 3006
Комментарии: 0
Изучаем pandas

 Читать далее...

12.03.2018г.
Просмотров: 3807
Комментарии: 0
Программирование на языке Rust (Цветное издание)

 Читать далее...

19.12.2017г.
Просмотров: 3820
Комментарии: 0
Глубокое обучение

 Читать далее...

19.12.2017г.
Просмотров: 6316
Комментарии: 0
Анализ социальных медиа на Python

 Читать далее...

19.12.2017г.
Просмотров: 3169
Комментарии: 0
Основы блокчейна

 Читать далее...

19.12.2017г.
Просмотров: 3459
Комментарии: 0
Java 9. Полный обзор нововведений

 Читать далее...

16.02.2017г.
Просмотров: 7277
Комментарии: 0
Опоздавших не бывает, или книга о стеке

 Читать далее...

17.05.2016г.
Просмотров: 10646
Комментарии: 0
Теория вычислений для программистов

 Читать далее...

30.03.2015г.
Просмотров: 12364
Комментарии: 0
От математики к обобщенному программированию

 Читать далее...

18.02.2014г.
Просмотров: 13998
Комментарии: 0
Рецензия на книгу «Читаем Тьюринга»

 Читать далее...

13.02.2014г.
Просмотров: 9123
Комментарии: 0
Читайте, размышляйте, действуйте

 Читать далее...

12.02.2014г.
Просмотров: 7078
Комментарии: 0
Рисуем наши мысли

 Читать далее...

10.02.2014г.
Просмотров: 5387
Комментарии: 3
Страна в цифрах

 Читать далее...

18.12.2013г.
Просмотров: 4616
Комментарии: 0
Большие данные меняют нашу жизнь

 Читать далее...

18.12.2013г.
Просмотров: 3426
Комментарии: 0
Компьютерные технологии – корень зла для точки роста

 Читать далее...

04.12.2013г.
Просмотров: 3154
Комментарии: 0
Паутина в облаках

 Читать далее...

03.12.2013г.
Просмотров: 3400
Комментарии: 0
Рецензия на книгу «MongoDB в действии»

 Читать далее...

02.12.2013г.
Просмотров: 3024
Комментарии: 0
Не думай о минутах свысока

 Читать далее...

Друзья сайта  

 Используем средства библиотеки OpenSSL для криптографической защиты данных. Часть 2

Архив номеров / 2006 / Выпуск №5 (42) / Используем средства библиотеки OpenSSL для криптографической защиты данных. Часть 2

Рубрика: Безопасность /  Механизмы защиты

Владимир Мешков

Используем средства библиотеки OpenSSL для криптографической защиты данных

Часть 2

Благодаря своим уникальным свойствам ассиметричные алгоритмы шифрования применяются для защиты информации в тех областях, где использование симметричных алгоритмов затруднительно. Это защита сообщений электронной почты, HTTP-трафика, организация безопасного доступа для удаленного администрирования (Security Shell). Самый популярный представитель семейства ассиметричных алгоритмов – алгоритм RSA.

Ассиметричные алгоритмы

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

Использование симметричной схемы шифрования требует передачи одного и того же ключа двум и более сторонам по независимому и надежному каналу. Этот канал должен исключать возможность утечки информации, обеспечивать полный контроль над процессом передачи ключа и гарантировать его доставку получателю. Когда количество абонентов невелико и расположены они недалеко друг от друга (например, в пределах одного города), гарантированно доставить ключ абоненту достаточно просто. А если абоненты находятся в разных городах или их количество очень велико? В таком случае организация надежного канала доставки ключевых данных – задача весьма непростая, требующая значительных затрат.

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

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

Алгоритм RSA. Теория

Криптосистема RSA, предложенная в 1977 году Ривестом (R. Rivest), Шамиром (A. Shamir) и Адлеманом (L. Adleman), предназначена для шифрования и цифровой подписи. В настоящее время RSA является наиболее распространенной криптосистемой – стандартом де-факто для многих криптографических приложений. Криптосистема RSA широко применяется в составе различных стандартов и протоколов Интернета, включая PEM, S/MIME, PEM-MIME, S-HTTP и SSL.

Криптографическая стойкость алгоритма RSA основана на трудоемкости разложения на множители (факторизации) больших чисел. Термин «большие» означает, что число содержит 100~200 и более двоичных разрядов. Открытый и секретный ключи являются функциями двух больших простых чисел. Рассмотрим на примере, как выполняется генерация ключей алгоритма RSA, но вместо больших чисел для простоты изложения будем использовать маленькие десятичные.

Для генерации парных ключей используются два случайных простых числа, p и q. Вычисляется произведение этих чисел n и значение функции Эйлера от числа n по формуле:

φ(n)=(p-1)(q-1)  [1]

Далее выбирается ключ шифрования e такой, что e и значение функции Эйлера φ(n) являются взаимно простыми числами, т.е. числами, не имеющими общих делителей, кроме единицы (единицу еще называют тривиальным делителем). Теперь необходимо найти значение ключа дешифрования d такое, чтобы выполнялось равенство:

ed = 1(mod φ(n)) [2]

или

d = e-1(mod φ(n)) [3]

Уравнение [2] означает, что остаток от деления произведения чисел e и d на значение функции Эйлера φ(n) должен быть равен 1.

Условие [2] выполняется только в том случае, если e и φ(n) являются взаимно простыми числами. Число d называется взаимно обратным к e по модулю φ(n). Уравнение [2] эквивалентно обнаружению таких d и v, что:

ed + φ(n)v = 1   [4]

Поиск обратного значения числа по модулю выполняется при помощи алгоритма Эвклида. Этот алгоритм позволяет найти наибольший общий делитель (НОД) двух чисел.

Рассмотрим пример. Пусть у нас имеются два простых числа: p=13 и q=17. Найдем произведение этих чисел:

n = 13 * 17 = 221

и значение функции Эйлера от числа n=221:

φ(n)=(p-1)(q-1)=(13-1)(17-1)=192

Теперь выберем такое число e, чтобы оно было взаимно простым с φ(n). Таким числом является, например, e=7. Далее надо найти обратное значение числа e, чтобы выполнялось уравнение [2]. Для этого с помощью алгоритма Эвклида ищем значения d и v, удовлетворяющие соотношению [4]. Суть алгоритма сводится к проведению последовательности операций деления с остатком. В соответствии с алгоритмом находим частное и остаток от деления φ(n) на e:

192 = 7 * 27 + 3

Частное равно 27, остаток – 3. Теперь последовательно делим делитель на остаток (т. е. 7 на 3 в данном случае) до тех пор, пока в остатке не получим единицу:

7 = 3 * 2 + 1

А теперь распишем процесс получения остатка в обратном порядке:

1 = 7 – 3 * 2 = 7 – (192 – 7 * 27) * 2 = 7 – (192 * 2 – 7 * 2 * 27)

Раскроем скобки:

1 = 7 + 7 * 54 – 192 * 2 = 7 * 55 – 192 * 2

В итоге получаем искомые числа d=55 и v=2. Числа d=55 и e=7 являются взаимно обратными по модулю 192, что подтверждает равенство:

7 * 55 = 1(mod 192)

Учитывая, что e=7 – это наш ключ шифрования, то число d=55 будет ключом дешифрования.

Теперь разберемся, как выполняются операции шифрования и дешифрования информации по алгоритму RSA.

Для шифрования исходное сообщение необходимо представить в виде последовательности чисел, содержащихся в интервале от 0 до n. Для примера, разобьем аббревиатуру ABC на числа в интервале (0,221). Для этого достаточно каждый символ записать в десятичном представлении:

A=41h=65, B=42h=66, C=43h=67

Шифрование сводится к вычислению:

Ci = Mie(mod n)

Здесь M– это i-й блок сообщения, Ci – результат криптопреобразования. Выражаясь простым языком, мы должны возвести значение Mi в степень e и найти остаток от деления на n.

Зашифруем нашу последовательность (65,66,67), зная, что e=7 и n=221:

C1 = 657(mod 221) = 91

C2 = 667(mod 221) = 144

C3 = 677(mod 221) = 50

В зашифрованном виде наша последовательность будет выглядеть как (91,144,50).

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

M= Cid(mod n)

Дешифруем последовательность (91,144,50) при d=55 и n=221:

M= 9155(mod 221) = 65

M2 = 14455(mod 221) = 66

M3 = 5055(mod 221) = 67

Таким образом, исходная последовательность восстановлена.

Шифрование RSA выполняется намного эффективнее, если правильно выбрать значение e. Чаще всего используются 3, 17 и 65537. Стандарт X.509 рекомендует 65537, PEM – 3, PKCS#1 – 3 или 65537.

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

Функции библиотеки для защиты информации по RSA-алгоритму

Прежде чем изучить вышеозначенные функции, приостановимся на минуту и подумаем – если мы оперируем с числами, разрядность которых составляет ~200 битов, то мы должны их где-то хранить. А ведь их надо не только хранить, но и проводить над ними различные математические операции, такие как умножение, деление, возведение в степень и т. п. Очевидно, что стандартные типы языка программирования Си, например, long или double long, и прямое использование функций стандартной библиотеки этого языка, таких как «+», «*» и т. п. для этих целей совершенно непригодны. Поэтому библиотека OpenSSL содержит ряд специальных функций для работы с большими числами, разрядность которых превышает разрядность адресной шины и регистров процессора. Для хранения этих чисел используется динамическая память. Базовым объектом библиотеки для работы с такими числами является объект типа BIGNUM. Этот тип определен в файле openssl/bn.h:

#define BN_ULONG unsigned char

typedef struct bignum_st

    {

    /* Pointer to an array of 'BN_BITS2' bit chunks. */

    BN_ULONG *d;

    int top; /* Index of last used d +1. */

    /* The next are internal book keeping for bn_expand. */

    int dmax; /* Size of the d array. */

    int neg; /* one if the number is negative */

    int flags;

    } BIGNUM;

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

  • BIGNUM * BN_new(void) – создает объект типа BIGNUM и возвращает указатель на него;
  • int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) – суммирует числа a и b, результат помещает в r (r=a+b);
  • int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) – выполняет операцию вычитания числа b из числа а, результат сохраняется в r (r=a-b);
  • int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) – умножает число a на число b и сохраняет результат в r (r=a*b). Последний параметр BN_CTX *ctx используется для хранения промежуточных результатов вычисления (а BN_CTX is a structure that holds BIGNUM temporary variables used by library functions);
  • int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *a, const BIGNUM *d, BN_CTX *ctx) – делит число a на b, частное сохраняется в dv, остаток – в rem (dv=a/b, rem=a%b).

Подробную информацию по функциям типа BN_* смотрите на странице руководства man bn.

Все ассимметричные алгоритмы, реализованные в библиотеке, такие как RSA, DSA, Diffie-Hellman, используют эти функции.

Генерация ключей алгоритма RSA

Как в и случае симметричных алгоритмов, для криптографической защиты информации по алгоритму RSA необходимо вначале сгенерировать открытый и секретный ключи. Генерацию ключей алгоритма RSA выполняет функция RSA_generate_key следующего вида:

RSA *RSA_generate_key(int num, unsigned long e, void (*callback)(int,int,void *), void *cb_arg);

Параметры функции:

  • int num – размер ключа в битах;
  • unsigned long e – это то самое число e, с которым мы познакомились в пункте 2, когда рассматривали теоретические основы алгоритма RSA. Этот параметр обычно принимает значения 3, 17 или 65537.

Два последних параметра, указатели на функцию (*callback) и void *cb_arg, служат для предоставления обратной связи (feedback) с процессом генерации ключевой информации. Это, как правило, индикация хода выполнения операции генерирования ключей. Например, если мы выполним команду:

openssl genrsa –out outfile 2048

то увидим, как на экране начнут появляться символы «.» и «+», отображающие процесс формирования ключей. Найдем в файле apps/genrsa.c исходных текстов библиотеки вызов функции RSA_generate_key:

rsa=RSA_generate_key(num,f4,genrsa_cb,bio_err);

Третий параметр – функция genrsa_cb – находится в этом же файле и имеет следующий вид:

static void MS_CALLBACK genrsa_cb(int p, int n, void *arg)

    {

    char c='*';

    if (p == 0) c='.';

    if (p == 1) c='+';

    if (p == 2) c='*';

    if (p == 3) c='\n';

    BIO_write((BIO *)arg,&c,1);

    (void)BIO_flush((BIO *)arg);

#ifdef LINT

    p=n;

#endif

    }

Как видно из текста этой функции, именно она выводит на экран символы «.» и «+», отображающие ход операции генерирования ключей.

Результаты работы функции RSA_generate_key в виде открытого и закрытого ключа сохраняются в структуре типа RSA (см. include/openssl/rsa.h). Эти ключи необходимо извлечь и записать в файлы для дальнейшей работы с ними. Делается это при помощи следующих двух функций:

int PEM_write_RSAPublicKey(FILE *fp, RSA *x);

int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u);

Первая функция записывает в файл fp открытый ключ, который находится в структуре типа RSA, на которую указывает параметр x. Вторая функция изымает секретный ключ из структуры x и записывает его в файл fp. Как правило, секретный ключ зашифровывают, что способствует повышению его защищенности. Выбор алгоритма шифрования выполняется с помощью параметра const EVP_CIPHER *enc (контекст алгоритма шифрования, см. первую часть статьи). Но для шифрования необходимо задать ключевую фразу (пароль), и сделать это можно несколькими способами.

Можно указать в параметре cb (сокращение от callback) адрес функции, которая будет запрашивать пароль. Если указатель kstr не будет равен NULL, то в качестве пароля будут использованы первые klen символов из массива, на который указывает kstr, при этом параметр cb игнорируется. Если cb == NULL, а параметр u не равен NULL, то u интерпретируется как строка, заканчивающаяся нулем, и эта строка используется как пароль. Также можно все параметры (kstr, cb, u) установить в NULL, и библиотека запросит у нас парольную фразу самостоятельно, используя свои внутренние механизмы.

Обобщим все вышесказанное в виде фрагмента программы, генерирующей ключи по алгоритму RSA, при этом секретный ключ шифруется по алгоритму Blowfish с обратной связью по выходу. Длина ключа – 2048 бит. В целях экономии места код, выполняющий обработку ошибок, пропущен.

Листинг 1. Генерация ключей алгоритма RSA

#include <stdio.h>

#include <openssl/rsa.h>

#include <openssl/pem.h>

/* Имена ключевых файлов */

#define PRIVAT "./privat.key"

#define PUBLIC "./public.key"

void main()

{

    /* указатель на структуру для хранения ключей */

    RSA * rsa = NULL;

    unsigned long bits = 2048; /* длина ключа в битах */

    FILE *priv_key_file = NULL, *pub_key_file = NULL;

    /* контекст алгоритма шифрования */

    const EVP_CIPHER *cipher = NULL;

    priv_key_file = fopen(PRIVAT, "wb");

    pub_key_file = fopen(PUBLIC, "wb");

/* Генерируем ключи */

    rsa = RSA_generate_key(bits, RSA_F4, NULL, NULL);

/* Формируем контекст алгоритма шифрования */

    OpenSSL_add_all_ciphers();

    cipher = EVP_get_cipherbyname("bf-ofb");

/* Получаем из структуры rsa открытый и секретный ключи и сохраняем в файлах.

 * Секретный ключ шифруем с помощью парольной фразы «hello»

 */

    PEM_write_RSAPrivateKey(priv_key_file, rsa, cipher,

    NULL, 0, NULL, "hello");

    PEM_write_RSAPublicKey(pub_key_file, rsa);

/* Освобождаем память, выделенную под структуру rsa */

    RSA_free(rsa);

}

Если в вызове функции PEM_write_RSAPrivateKey мы вместо «hello» оставим NULL, то библиотека самостоятельно попросит наc ввести парольную фразу для шифрования секретного ключа.

Шифрование и дешифрование по алгоритму RSA

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

int RSA_public_encrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa, int padding);

Эта функция шифрует flen байт из буфера, на который указывает параметр from, используя ключ из структуры RSA * rsa, и помещает результат в буфер to. Размер этого буфера должен быть равен размеру ключа, который определяется при помощи функции RSA_size(RSA *).

Параметр padding используется для выбора режима выравнивания данных. В большинстве случаев используется значение RSA_PKCS1_PADDING, что соответствует стандарту PKCS#1. При использовании этого режима размер буфера from должен быть не меньше (RSA_size(rsa) – 11), т.е. на 11 байт меньше размера ключа. Размер выходных данных всегда будет кратен длине ключа.

Следующая программа демонстрирует использование функции RSA_public_encrypt для шифрования данных.

Листинг 2. Шифрование данных по алгоритму RSA

#include <openssl/rsa.h>

#include <openssl/pem.h>

void main(int argc, char **argv)

{

    /* структура для хранения открытого ключа */

    RSA * pubKey = NULL;

    unsigned char *ptext, *ctext;

    FILE * pub_key_file = NULL;

/* Открываем входной и создаем выходной файлы */

    int inf = open(argv[1], O_RDWR);

    int outf = open("./rsa.file",

    O_CREAT|O_TRUNC|O_RDWR, 0600);

/* Считываем открытый ключ */

    pub_key_file = fopen(PUBLIC, "rb");

    pubKey = PEM_read_RSAPublicKey(pub_key_file, NULL, NULL, NULL);

/* Определяем длину ключа */

    int key_size = RSA_size(pubKey);

    ptext = malloc(key_size);

    ctext = malloc(key_size);

/* Шифруем содержимое входного файла */

    while(1) {

    inlen = read(inf, ptext, key_size - 11);

    if(inlen <= 0) break;

    outlen = RSA_public_encrypt(inlen, ptext, ctext, pubKey, RSA_PKCS1_PADDING);

    if(outlen != RSA_size(pubKey)) exit(-1);

    write(outf, ctext, outlen);

    }

}

Дешифрование данных выполняет функция RSA_private_decrypt:

int RSA_private_decrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa, int padding);

Эта функция расшифровывает flen байт из буфера from, используя ключ rsa, и записывает результаты в буфер to.

Следующий фрагмент программы демонстрирует использование функции RSA_private_decrypt для дешифрования данных.

Листинг 3. Дешифрование файла, зашифрованного по RSA-алгоритму

#include <openssl/rsa.h>

#include <openssl/pem.h>

void main(int argc, char **argv)

{

    RSA *privKey = NULL;

    FILE *priv_key_file;

    unsigned char *ptext, *ctext;

/* Открываем входной и создаем выходной файл */

    inf = open(argv[1], O_RDWR);

    outf = open("./test.rsa", O_CREAT|O_TRUNC|O_RDWR, 0600);

/* Открываем ключевой файл и считываем секретный ключ */

    priv_key_file = fopen(PRIVAT, "rb");

    privKey = PEM_read_RSAPrivateKey(priv_key_file, NULL, NULL, NULL);

/* Определяем размер ключа */

    key_size = RSA_size(privKey);

    ctext = malloc(key_size);

    ptext = malloc(key_size);

/* Дешифруем файл */

    while(1) {

    inlen = read(inf, ctext, key_size);

    if(inlen <= 0) break;

    outlen = RSA_private_decrypt(inlen, ctext, ptext, privKey, RSA_PKCS1_PADDING);

    if(outlen < 0) exit(0);

    write(outf, ptext, outlen);

    }

}

Работоспособность программ была проверена для ОС Linux Slackware 10.2, библиотека OpenSSL версии 0.9.7c

Итак, вы разобрались с теоретическими основами алгоритма RSA и научились использовать некоторые функции библиотеки для защиты информации по этому алгоритму. Я говорю «некоторые», потому что этих функций в библиотеке очень много, и описать их в одной статье практически невозможно. Поэтому основным источником изучения средств библиотеки были и остаются официальная документация от разработчиков, а также любые исходные тексты программ, использующих эту библиотеку.


Комментарии
 
  04.10.2011 - 03:50 |  Дмитрий

При считывании открытого ключа из файла программа вылетает. (Windows) Почему?

  04.10.2011 - 05:23 |  Коля

Бывает, если ключ создаешь не из программы, а с помощью openssl блаблабла

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-45
E-mail: sa@samag.ru