Про криптографию в терминале

Шифрование соединения с сервером происходит в случае, когда в connections.xml
для соответствующего сервера указан атрибуты ciphered="true" и publicKey="...".
publicKey содержит открытый ключ сервера в формате X.509 и закодирован base64.
Шифрование соединения осуществляется с помощью алгоритма DES. Для этого терминал
генерирует секретный сессионный 56-ти битный ключ. Отправка сессионного ключа
серверу осуществляется с помощью алгоритма RSA с длиной ключа 1024 бит.

Процедура обмена сессионым ключом

1. Генерация 56-ти битного ключа DES.
2. Заворачивание сессионного ключа алгоритмом RSA/ECB/PKCS1Padding для получения
   сообщения M.
3. Подписывание сообщения M с помощью закрытого ключа терминала для получение
   подписи S.
4. Установка флагов BINARY_DATA, GET_CRYPTO_KEY, ROW_TEXT_DATA
5. Отправка сообщения в следующем формате:
          0   1   2   3
      0 +---+---+---+---+
        |  размер сообщ |
      1 +---+---+---+---+
        | зашифрованный |
        /  сессилнный   /
        /     ключ      /
        |               |
    129 +---+---+---+---+
        |               |
        /    подпись    /
        /               /
        |               |
        +---+---+---+---+
6. Сервер проверяет подпись, расшифровывает сессионный ключ и отправляет
   его обратно терминалу таким же образом.
7. Чтение ответа сервера. Если произошла ошибка, то будет установлен флаг
   SYSTEM_ERROR. При этом сообщение будет содержать код ошибки, пробел,
   текст ошибки. Коды ошибок следующие:
   
   0 - ключ не зарегистрирован
   1 - срок ключа истек
   2 - левый ключ. Сервер ничего не знает об этом ключе
   
8. Проверка подписи сервера и сравнение полученного сессионного ключа с
   отправленным. Таким образом терминал убеждается, что обмен сессионым
   ключом прошел успешно.

Текущий и запасной ключи

Имеется два ключа: текущий и запасной. Текущий ключ - рабочий ключ терминала
с которым он работает. Текущий ключ имеет срок годности по истечении которого
он перестает работать. Если создан запасной ключ, то автоматически запасной
ключ становиться текущим. При этом пользователь должен позаботиться о
создании нового запасного ключа.

Терминал отводит место для хранения 2-х ключей. Сервер имеет 3 места для
хранения ключей терминала.

+----------------------+------------------------------------------+
|    терминал          |                  сервер                  |
|                      |                                          |
|  +-----------+                               +---------------+  |
|  | 1-ый ключ |______       +-------+    _____| текущий ключ  |  |
|  +-----------+      \______|       |___/     +---------------+  |
|                      ______| буфер |___                         |
|  +-----------+______/      |       |   \_____+---------------+  |
|  | 2-ой ключ |             +-------+         | запасной ключ |  |
|  +-----------+       |                       +---------------+  |
|                      |                                          |
+----------------------+------------------+-----------------------+
|        новый         | неподтвержденный |   текущий/запасной    |
+----------------------+------------------+-----------------------+

Таким образом, ключ имеет один из четырех статусов:

Новый - сгенерированный на терминале ключ
Неподтвержденный - сгенерированный ключ отправлен на сервер. Ключ
находится в буфере сервера. Пользователь отправляет по почте/факсу и т.д.
дайджест отправленного ключа.
Запасной ключ - ключ из буфера (неподтвержденный) становиться запасным.
Текущий ключ - ключ из буфера (неподтвержденный) становиться текущим.

Обмен открытыми ключами

Терминал отправляет открытый ключ серверу с помощью запроса:

<term_pub_key>
    <pub_key>...</pub_key>
</term_pub_key>

После помещения ключа в буфер сервера приходит ответ:

<term_pub_key>
    <digest>...</digest>
</term_pub_key>

где digest это отпечаток открытого ключа.

Получение информации о ключах

Терминал запрашивает информацию о своих открытых ключах запросом:

<term>
    <query handle="0">
	    <key_info/>
    </query>
</term>

Ответ сервера:

<term>
    <answer handle="0">
        <key_manager>
            <key state="current | future">DIGEST</key>
            <unconfirmed>DIGEST</unconfirmed>
            <expiration>hh:mm DD.MM.YY</expiration>
        </key_manager>
    </answer>
</term>

Атрибут state тега <key> может быть либо current либо future.
current говорит о том, что это текущий ключ терминала. future - запасной.
<unconfirmed> - ключ, который находится в буфере.
<expiration> - срок годности подтвержденного ключа. Таким образом
терминал информирует пользователя о состоянии ключей.
Назад