Побег из КриптоПро
Yesterday

Побег из КриптоПро (ч.4, final?)

В третьей части цикла статей "Побег из КриптоПро" был разобран экспорт приватного ключа из проприетарного формата ключевого контейнера (те самые 6 файлов .key), а в цикле "Тащим ключи с Рутокен Lite" собственно был разобран экспорт самого контейнера с токена. Однако остался главный нерешённый вопрос, из-за которого экспорт контейнера штатными средствами "Панели администрирования Рутокен" и КриптоПро был невозможен - флаг экспортируемости контейнера.

Важно: не следует путать понятие неэкспортируемости и неизвлекаемости. Неэкспортируемый контейнер - контейнер, на который наложено софтовое ограничение на экспорт, т.е если программа проигнорирует этот флаг, то она сможет произвести экспорт. Понятие неизвлекаемости относится к токенам с механизмом ФКН (Функциональный ключевой носитель, аля PKCS#11), где сам ключ генерируется на токене и никогда не покидает его (такая возможность попросту отсутствует), все операции вплоть до вычисления хэшей выполняются на самом токене.

Его величество - флаг...

Почему флаг? - Потому, что как оказалась всё софтовое ограничение, запрещающее экспорт, представляет из себя значение в 1 бит. Т.е "1" - экспорт разрешён, а "0" - экспорт запрещён. Такие дела...

А если подробнее?

Давайте взглянем на файл header.key с помощью декодера ASN.1:

Размеченное содержимое header.key

Мы видим всю открытую информацию о контейнере, например байты сертификата под тегом 5, или кусочек публичного ключа под тегом 8, или HMAC для проверки пароля контейнера под тегом 2. Но в данном случае нас интересуют другие данные, а именно 2 SEQUENCE (выделены оранжевым и зелёным). В одном из них мы можем заметить BIT STRING с 3 битами (выделены жёлтым). Данные биты - это параметры приватного ключа. Собственно первый бит и есть флаг экспортируемости. Вообще вся структура там следующая:

Структура битов для параметров приватного ключа

Однако, что за значение выделенное красным? - Это MAC всего контейнера, если мы просто изменим флаг, но не пересчитаем MAC, то КриптоПро такой контейнер не примет. (Кстати подобная схема используется и в экспортном представлении приватного ключа)

Пересчитываем MAC контейнера

Сам алгоритм вычисления MAC довольно прост:

  1. Берём SEQUENCE выделенный оранжевым и сериализуем его в байты;
  2. Вычисляем MAC с помощью шифра Магма (ГОСТ 28147-89) со следующими параметрами:
    - Ключ: 32 нулевых байта
    - IV/Соль: 8 нулевых байт
    - Данные: сериализованый ранее SEQUENCE
    - Набор параметров (SBox) - ID_TC26_GOST_28147_PARAM_Z
  3. Подставляем получившейся в MAC (если MAC больше 4 байт то берём только первые 4 байта) в ASN.1 структуру, сериализуем в байты и записываем их в файл
  4. Profit!

В результате изменения бита в параметрах приватного ключа и применения алгоритма вычисления MAC контейнера мы смогли успешно "пролечить" контейнер разрешив экспорт.

Бонус. Как вычисляются остальные MAC

MAC маски и соли

Размеченное содержимое masks.key

Вычисляем MAC с помощью шифра Магма (ГОСТ 28147-89) со следующими параметрами:
- Ключ: Значение маски (выделено жёлтым, если больше 32 байтов, то берём последние 32 байта)
- IV/Соль: 8 нулевых байт
- Данные: Значение соли (выделено оранжевым)
- Набор параметров (SBox) - ID_TC26_GOST_28147_PARAM_Z

Если MAC больше 4 байт то берём только первые 4 байта

MAC пароля

Размеченное содержимое masks.key
  1. Прогоняем через CPKDF (CryptoPro Key derivation function) пароль (в качестве соли для CPKDF берём 8 байт куска публичного ключа (в ASN.1 под тегом 10, на рисунке выделено жёлтым)
  2. Вычисляем MAC с помощью шифра Магма (ГОСТ 28147-89) со следующими параметрами:
    - Ключ: Результат из п.1
    - IV/Соль: 8 нулевых байт
    - Данные: 16 нулевых байт
    - Набор параметров (SBox) - ID_TC26_GOST_28147_PARAM_Z
  3. Если MAC больше 4 байт то берём только первые 4 байта

На этом у меня всё, все ASN.1 схемы, а также практические реализации алгоритмов вычисления MAC вы можете найти в исходном коде @li0ard/cpfx. Также туда в скором времени выйдет обновление добавляющее автоматическое изменение флага экспортируемости с пересчётом MAC.