КЭП от зеленого оператора сотовой связи

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


Попытка победить «своими силами»

Ранее использование МЭП от Мегафон было доступно в софте Криптоарм ГОСТ (только режим подписания документов), на данный момент, судя по гитхаб, поддержку выпилили полностью.


Попробуем реализовать подпись документов собственноручно:


Адрес для подписи документов: https://msign.megafon.ru/mes-ws/sign?wsdl=

Адрес для отслеживания статуса заявки на подпись: https://msign.megafon.ru/mes-ws/status?wsdl=


Отправка документа на подпись (/mes-ws/sign)


Входные параметры для отправки документа на подпись:

partner_id - идентификатор партнера, осуществляющего операцию подписания (возьмем из Крипто АРМ – digt)

msisdn - мобильный номер SIM-карты клиента с КЭП

text - текст, который будет отображен на Мобильном Устройстве Абонента при подписании документа

document - подписываемый документ в формате base64

signType - тип подписи, возможные значения: Attached – прикрепленная подпись и Detached – открепленная подпись (Если параметр отсутствует, платформа создает detached подпись)

digest - специфицируемая «свертка» от документа (8 шестнадцатеричных символов)


Правила формирования свертки (поле digest):

1) Вычисляется MD5 от представления документа в формате Base64

2) В цикле от 0 до 8 вычисляется XOR от I, I+8, I+16, I+24

3) Полученные шестнадцатеричные цифры конкатенируются в строковом

представлении


function md5_to_digest($md5) {
$result = '';
for($i=0; $i<8; $i++) {
for($j=0; $j<4; $j++) {
$digit = substr($md5, $i+$j*8, 1);
$d16 = hexdec($digit);
if($j == 0) {
$r = $d16;
} else {
$r = $r ^ $d16;
}
}
$result .= dechex($r);
}
return strtoupper($result);
}

Возвращаемые параметры:

transaction_id - уникальный идентификатор транзакции


Получаем статус обработки документа (/mes-ws/status)


Для проверки статуса передаем параметры partner_id и transaction_id, в результате получаем ответ от сервера, который содержит поле status


Если статус равен 100, то все хорошо и поле cms будет содержать электронную подпись документа в формате Base64


В противном случае смотрим код ошибки из списка:

101 - Документ еще не подписан

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

201 - Один из параметров имеет неверный формат

203 - Неизвестный идентификатор транзакции

400 - Неизвестный partner_id

401 - Неизвестный сертификат SSL или сертификат SSL не соответствует парнёру (partner_id).

500 - Внутренняя ошибка сервера повторите запрос позже

800 - Время жизни транзакции истекло

801 - Сервер подписания не смог доставить запрос на подписание на мобильное устройство

802 - Абонент отказался подписывать документ

803 - Заблокирован PIN

804 - SIM карта заблокирована

805 - На SIM карте нет ключевой пары

806 - Ошибка в сертификате Абонента

807 - Запрос на подписание не может быть выполнен необходимо сформировать новый запрос на подписание


У конкурентов есть DSS сервера от КриптоПро, которые позволяют решить большинство задач посредством сторонних сервисов, в Мегафон почему –то отказались от подобной практики.


Реверс-инжиниринг DSS непростая задача, но удалось заставить работать подгрузку сертификатов в другие программы.