Про криптографию в терминале
Шифрование соединения с сервером происходит в случае, когда в 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> - срок годности подтвержденного ключа. Таким образом
терминал информирует пользователя о состоянии ключей.
Назад