Криптография
June 23

Побег из КриптоПро (ч.3)

В прошлых частях (клик, клик) я разбирался с транспортным ключевым контейнером от КриптоПро (он же PFX, PKCS12, P12). В этой статье пойдёт речь о собственном формате ключевого контейнера КриптоПро (те самые 6 файлов .key)

Проприетарный контейнер КриптоПро

Вообще тема данной статьи не нова, ещё в далёком 2016 года Михаил Куликов (он же shukan) написал статью на Хабре в которой он предоставил программу на C, которая вытаскивала ключ для ГОСТ 34.10-2001. Чуть позже благодаря сообществу появилась версия и для ГОСТ 34.10-2012. Однако пробуя запустить все эти утилиты для контейнера ГОСТ 34.10-2012 512 бит сгенерированного в КриптоПро CSP 5.0, утилиты выдавали ошибку. Собственно это и стало мотивацией разобраться как там всё устроено и написать свою программу.

Как там всё устроено

Файл masks.key

Содержимое masks.key

Содержит в себе три Octet String, которые в свою очередь являются маской ключа (32 байта для 256 бит, 64 для 512), солью для деривации пароля и контрольной суммы маски соответственно.

Файл primary.key

Содержимое primary.key

Содержит зашифрованный приватный ключ (32 байта для 256 бит, 64 для 512), который после расшифровки надо разделить по модулю на поле Q эллиптической кривой ключа.

Файл header.key

Содержимое header.key

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

Получаем приватный ключ

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

  1. Получение так ключа хранения с помощью CPKDF (CryptoPro Key Derivation Function) в которую передаётся пароль и соль из файла masks.key.
  2. Расшифровка основного ключа с помощью ГОСТ 28147-89 (Магма) в ECB режиме с параметрами набора Z от ТК-26
  3. Деление по модулю расшифрованного ключа на маску
  4. Подстановка результата в ASN.1 конструкцию приватного ключа

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

Также хочу выразить благодарность Савелию Красовскому за его утилиту go-decrypto-pro, которая стала основной для моей программы, и VovkaTM за консультации и прочую помощь.

Ссылки

Программа - https://github.com/li0ard/ckey

Утилита go-decrypto-pro - https://github.com/savely-krasovsky/go-decrypto-pro