MiniM. Saving time.


| About | Download | Tools | Knowledge Base | How to Buy |

MiniM Overview

Getting Started

Download

Documentation

Tools

Cache Tools

GT.M Tools

Knowledge Base

FAQ

Contacts

Copyrights

MiniM Additional Tools | Sep 12, 2010

Работа с устройством |ZSSL|

(базовая версия с использованием библиотеки OpenSSL)

Используемые материалы:
http://www.openssl.org/
http://www.opensslbook.com/
http://www.opennet.ru/base/sec/openssl.txt.html
http://www.cryptocom.ru/products/cryptopacket.html
http://www.ibm.com/developerworks/ru/library/l-openssl3/
http://www.minimdb.com/
http://www.minimdb.com/tools/inetd.html

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

Для всех примеров используется в качестве сервера OpenSSL. Пароль для всех сертификатов "12345" (или не используется вообще, зависит от того как вы генерили ключи).

Простой SSL-сервер, запускаем следующим образом:

openssl.exe s_server -accept 16001 -cert server.pem -debug


Рис. 1

Запуск демо-сервера HTTPS:

openssl.exe s_server -WWW -accept 16001 -cert server.pem -debug

Устройство поддерживает два режима работы: клиент и сервер, с использованием внешних ключей или с использованием "эфемерных" ключей.

Как использовать устройство |ZSSL| в режиме клиента.

1) Создать устройство,указать параметры работы.

open "|ZSSL|hostname:port" или open "|ZSSL|":(/param=value,...)

Параметры/param можно передавать следующие:

ПараметрОписание
/CONNECT="host:port"адрес:порт куда выполням коннект или передать, вместе с "|ZSSL|host:port".

Не использовать совместно с /MODE,/SOCKET

/CERT="/путь/к/Сертификату.pem"сертификат клиента
/KEY="/путь/к/секретному/ключу.pem"если /KEY не определен, то используется значение из /CERT, если он защищен паролем, то необходимо передать опцию /PWD первой!
/PWD="пароль"пароль к ключа (если требуется), желательно /PWD передать до использования опции/CERT или /KEY
/MODE=0указать, что режим работы "клиент", если в контексте вызова система не зает, что за режим получается
/SOCKET=номер_сокетауказывает,что соеденение установили другими ср-вами, например чрез open "|TCP|" номер_сокета определяется как (псевдокод):

u "|TCP|" s socketno=$v("dev",2)

/MODE,/SOCKET приоритетней, чем /CONNECT

/CAFILEСертификат СА
/CAPATHПуть где искать цепочки сертификатов

2) Сделать его текущим:

use "|ZSSL|"

3) Устройство готово к обмену:

use "|ZSSL|"
write "Hello SSL!",$c(13,10)

4) Отключить:

close "|ZSSL|"

Пример 1. Обычный доступ к данным(ключи генерятся на "лету"):

USER>s dev="|ZSSL|localhost:16001"
USER>o dev
USER>u dev w "Hello SSL!",$c(13,10)
USER>c dev

Ответ сервера (частично, «Hello…» будет на сл. экране):


Рис. 2


Рис.3

Пример 2. С использованием готовых ключей:

USER>s dev="|ZSSL|localhost:16001"
USER>o dev:(/PWD="12345":/CERT="client.pem")
USER>u dev w "Hello SSL!",$c(13,10)
USER>c dev

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

После установки корректного соеденения, весь обмен через устройство "|ZSSL|" будет осуществлятся в режиме прозрачного шифрования, по умолчаню выбираются максимальные настройки, на данный момент OpenSSL 1.0.0 использует алгоритм ECDHE-RSA-AES256-SHA и далее в порядке перечисления:

ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-SHA:
DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:
DHE-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA:
ECDH-ECDSA-AES256-SHA:AES256-SHA:CAMELLIA256-SHA:
ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:
EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:
ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:
DES-CBC3-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:
DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-SEED-SHA:
DHE-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA

Пример 2: Чтение странички с сайта(с ошибками)

https://banking.webmoney.ru/asp/banking.asp
USER>s c=$c(13,10),dev="|ZSSL|www.banking.webmoney.ru:443" o dev
USER>u dev w "GET /asp/banking.asp HTTP/1.1",c,c r s
USER>c dev u 0 w s
s="HTTP/1.1 400 Bad Request
Content-Type: text/html
Date: Tue, 06 Jul 2010 18:54:08 GMT
Connection: close
Content-Length: 39
 
<h1>Bad Request (Invalid Hostname)</h1>"

Как использовать устройство |ZSSL| в режиме сервера.

1) Открыть соеденение стандартными ср-вами , используя устройство |TCP|.

s dev="|TCP|"_port open dev::1 e  w "error",! Q
или использовать routine ^%INETD (http://www.minimdb.com/tools/inet d.html) и подключить на выбранный вами порт, собственного «демона».
i $$ADD^%INETD("%srv","cdmn^%srvssl","%SYS",16001,"RWB",1)

2) Получить внутренний номер «акцепнутого» device.

S socket=$v("dev",1,dev)

2.1) сделать job для отвязывания «клиента» и «сервера», если используете %INETD делать не надо.

 u dev:(/ACCEPT:/ATO=0) s socket=$v("dev",2)
 j runcmd():(:$io)
 ...
 q
 ;
runcmd()
 u 0
 s %DEVICE=$i,%SOCKET=$v("dev",1)  ;из (:$io)
 ...
 o "|ZSSL|":(/SOCKET=%SOCKET,...)
или при использовании ^%INETD использовать переменную %SOCKET

3) Создать устройство, указать параметры работы.

open "|ZSSL|":(/param=value,...)

Параметры/param можно передавать следующие:

ПараметрОписание
/CERT="/путь/к/Сертификату.pem"сертификат сервера, обязателен!
/KEY="/путь/к/секретному/ключу.pem"если /KEY не определен, то используется значение из /CERT, если он защищен паролем, то необходимо передать опцию /PWD первой!
/PWD="пароль"пароль к сертфикату (если требуется), желательно /PWD передать до использования опции/CERT или /KEY
/MODE=1указать, что режим работы "сервер"
/SOCKET=номер_сокетаУказывает на номер вн. «акцепнутого» device
/CAFILEСертификат СА
/CAPATHПуть где искать цепочки сертификатов

Обратите внимание, что наличие параметра /CERT или /KEY строго обязательно, поскольку для серверов генерации эфемерных ключей в момент создания сессии не предусмотрено, в т.ч. необходимо обязательно передать /PWD до /CERT/KEY. При обращении клиента к серверу, клиент должен иметь корректный сертфикат сервера, иначе возможны проблемы при хендшейке (отказ в обслуживании).

4) В дальнейшем в/в осуществляется как и в режиме клиента, главное, что если необходимо получить новое клиентское соеденение, то выполнить пп. 2-3, т.е. |ZSSL| выполняет только роль «крипто» канала.

5) Закрытие устройства выполнять в обратном порядке, сначала |ZSSL| затем |TCP|.

См. пример %zssld.r

Использование библиотеки в качестве модуля ZDLL (см описание функции $zdll)

Библиотека поддерживает интерфейс $zdll, реализованы следующие функции:

$zdll("call","zssl.dll","version")

Возвращает версию openssl и версию библиотеки zssl.dll

$zdll("call","zssl.dll","RAND_write_file"[,filename])

Сохраняет 1024 байта псевдослучайных данных в файле, по умолчанию zssl.rnd.
Файл необходим для корректной работы механизма генерации «псевдослучайности». Никому данный файл не передавать, по возможности периодически удалять. Возвращает сколько реально байт записали в файл (обычно 1024 байт).

$zdll("call","zssl.dll","RAND_load_file"[,filename])

Подгружает файл псевдослучайных данных для «улучшения» статистики при генерации псевдослучайного потока данных/ключей и т.д., по умолчанию используется имя файла zssl.rnd. Возвращает сколько реально байт прочитали из указанного файла.


Рис.4

$zdll("call","zssl.dll","RAND_bytes"[,countbytes])

Возвращает криптографически стойкую последовательность псевдослучайных байт, т.к. при генерации контекста используются системные процессы, то генерация большого числа данных может занять значительное время. Рекомендуется использовать совместно с RAND_pseudo_bytes, например использовать до 8-16 байт RAND_bytes, а далее RAND_pseudo_bytes. Если параметр countbytes не указан возвращается MINIM_STR_MAX размер, будьте внимательны, может подвесить процесс!

$zdll("call","zssl.dll","RAND_pseudo_bytes"[,countbytes])

Быстрая генерация псевдослучайных байт. Возвращает строку байт, длиной countbytes, если параметр не указан, то генерируется MINIM_STR_MAX байт.


Рис. 5

$zdll("call","zssl.dll","EVP_Digest",algoritm,string)

Возвращает подпись/хеш на указанную строку,возвращаемая длина блока зависит от используемого алгоритма. Пример:

s dg=$zdll("call","zssl.dll","EVP_Digest","MD5","Hello MINIM!")
Вернет 16 байт. В зависимости от реализации библиотека поддерживает наиболее различные алгоритмы: md4, md5, mdc2, rmd160, sha, sha1, sha512 и тд. Алгоритмы ГОСТ в данной версии не поддерживаются.


Рис. 6

$zdll("call","zssl.dll","EVP_DigestInit",algoritm)
$zdll("call","zssl.dll","EVP_DigestUpdate",ctx,string)
$zdll("call","zssl.dll","EVP_DigestFinal",ctx)

Если возникла потребность сформировать хеш на блок размером более чем MINIM_STR_MAX , то можно воспользоватся указанными функциями. EVP_DigestInit инициализирует контекст указанного алгоритма, а EVP_DigestUpdate добавляет к контексту данные, EVP_DigestFinal – окончательно финализурует хеш, возвращает его значение и освобождает контекст. Пример использования:

S ctx=$zdll("call","zssl.dll","EVP_DigestInit","MD5"),i=""
F  S i=$o(str(i)) Q:i=""   I  \\ строка продолжается дальше
  $zdll("call","zssl.dll","EVP_DigestUpdate",ctx,str(i))
S dg=$zdll("call","zssl.dll","EVP_DigestFinal",ctx)

Не потеряйте контекст, переменную типа ctx в примере, иначе будет утечка памяти (при завершении процесс по hang утечка памяти нейтрализуется, т.е. актуально только для тек. процесса).

$zdll("call","zssl.dll","HMAC",algoritm,key,string)

Возвращает хеш HMAC (hash message authentication code), функционал полностью аналогичен функции EVP_Digest. Key-ключ для «устрашения» хеша. ;-)


Рис. 7

$zdll("call","zssl.dll","HMAC_Init",algoritm,key)
$zdll("call","zssl.dll","HMAC_Update",ctx,string)
$zdll("call","zssl.dll","HMAC_Final",ctx)

HMAC_Init initializes a HMAC_CTX structure to use the hash function evp_md and the key key which is key_len bytes long.
HMAC_Update can be called repeatedly with chunks of the message to be authenticated (len bytes at data).
HMAC_Final places the message authentication code in md, which must have space for the hash function output.
Функционал полностью совпадает с EVP_Digest*. Пример:

S ctx=$zdll("call","zssl.dll","HMAC_Init","RIPEMD160","key"),i=""
F  S i=$o(str(i)) Q:i=""     \\ строка продолжается ниже
   I $zdll("call","zssl.dll","HMAC_Update",ctx,str(i))
S dg=$zdll("call","zssl.dll","HMAC_Final",ctx)

$zdll("call","zssl.dll","HMAC_set_flags",mode)

Установка специфических опций, для каждого алгоритма HMAC устанавливаются свои значения, уточняйте в документации на библиотеку OpenSSL функция HMAC_CTX_set_flags. Вызывать после HMAC_Init но до первого использования HMAC_Update или HMAC_Final.

$zdll("call","zssl.dll","EVP_Encrypt",algoritm,key,iv,string)

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

S strcry=$zdll("call","zssl.dll","EVP_Encrypt","RC4","key","","Hello!")

Доступные алгоритмы(algoritm) симметричного де/шифрования (алгоритмы rsa/dsa не реализованы в данной версии zssl.dll):

aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb
aes-256-cbc       aes-256-ecb       base64            bf
bf-cbc            bf-cfb            bf-ecb            bf-ofb
camellia-128-cbc  camellia-128-ecb  camellia-192-cbc  camellia-192-ecb
camellia-256-cbc  camellia-256-ecb  cast              cast-cbc
cast5-cbc         cast5-cfb         cast5-ecb         cast5-ofb
des               des-cbc           des-cfb           des-ecb
des-ede           des-ede-cbc       des-ede-cfb       des-ede-ofb
des-ede3          des-ede3-cbc      des-ede3-cfb      des-ede3-ofb
des-ofb           des3              desx              idea
idea-cbc          idea-cfb          idea-ecb          idea-ofb
rc2               rc2-40-cbc        rc2-64-cbc        rc2-cbc
rc2-cfb           rc2-ecb           rc2-ofb           rc4
rc4-40            seed              seed-cbc          seed-cfb
seed-ecb          seed-ofb

$zdll("call","zssl.dll","EVP_EncryptInit",algoritm,key,iv)
$zdll("call","zssl.dll","EVP_EncryptUpdate",ctx,string)
$zdll("call","zssl.dll","EVP_EncryptFinal",ctx)

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

$zdll("call","zssl.dll","EVP_Decrypt",algoritm,key,iv,stringcry)

Возвращает дешифрованную строку, функция обратна EVP_Encrypt.

$zdll("call","zssl.dll","EVP_DecryptInit",algoritm,key,iv)
$zdll("call","zssl.dll","EVP_DecryptUpdate",ctx,string)
$zdll("call","zssl.dll","EVP_DecryptFinal",ctx)

Аналогично работают и EVP_Decrypt*. Обратны EVP_Encrypt*
В случае проблем все функции генерят Z-ошибку. Если у вас уже существует не нулевой контекст, то незабудьте его освободить, т.е. независимо от наличия ошибки выполнить финализацию (функции типа *Finale*).

См. примеры в zssltest.rsa

Инсталляция библиотеки

1. Скопируйте файл zssl.dll в директорию, куда установлен MINIM. Например:

copy zssl.zdll c:\minim\bin\

2. Если у вас в поставке есть исходный текст zssl.c и вы его модифицировали, то рекомендую собирать его компилятором VC++ ver 7 и выше, или Borland 5.0 C++ (free версия). Для примера, приложены .bat файлы для сборки обоими компиляторами.

Прочее

1. В качестве примера приложены .bat файлы для запуска OpenSSL в режиме клиента и сервера.

2. Ключи server.* и client.* рекомендую сгенерировать самостоятельно, заодно изучите командную строку OpenSSL.

3. Также желательно ознакомиться с выше приведенными ссылками, дополнительно в каталоге doc-add , есть различные материалы и примеры работы с SSL

Download zssld.zip (ZIP, 2.2Mb)

Alexander Chudnovsky
azbuka@rbcmail.ru
ICQ:144312645


Copyright (C) 2017 Eugene Karataev
Emails: Info Tech Support