Как и многие другие страны, Россия для официального электронного документооборота использует x509 сертификаты, выпускаемые уполномоченными Российскими Удостоверяющими Центрами (УЦ). И в отличие от многих других стран, использует свои собственные шифры.

Я давно хотел автоматизировать проверку подписей ответов органов власти (я много переписываюсь) и проверку «выгрузок» Роскомнадзора на подлинность (по роду общественной деятельности). Самой большой проблемой было достать промежуточные сертификаты из цепочки. Потому что существовал невнятный Excel-файл корневых УЦ на сайте Минсвязи и всё. А промежуточные надо было искать по сайтам соответствующих УЦ. Жизнь — боль.
Что такое «промежуточные сертификаты». Напомню как это работает. Допустим, мы хотим проверить некое подписанное письмо. Письмо подписано ключом. Есть сертификат, который удостоверяет этот ключ. Сертификат кем-то выдан и тоже подписан каким-то ключом с прилагаемым сертификатом. И тот сертификат точно также. И так до момента, когда сертификат выдан сам себе. При проверке мы имеем (принесли, поставили из пакета, нам выдали на флешке) некий набор вот этих конечных сертификатов, которым мы верим. Верим потому что мы верим тому, кто нам их выдал. В мире веба мы верим браузеру и их набору корневых сертификатов. В мире веба при соединении по HTTPS передаются от сервера к клиенту также и промежуточные сертификаты. Поэтому в мире веба у нас всегда есть вся цепочка.
Внезапно (я не знаю точно когда) и незаметно на сайте Госуслуг появилась вот такая ссылочка:
e-trust.gosuslugi.ru/CA

Я наскоро написал программку, которая превращает XML-файл со списком УЦ и сертификатами с этого сайта в привычный PEM формат.

Затем я автоматизировал её и получил постоянно поддерживаемый репозиторий сертификатов в привычном для *NIX мира виде.

Шифрование ГОСТ


Шифрование ГОСТ поддерживается в LibreSSL не помню с какой версии. Но в Alpine Linux от 3.5 уже поддерживается. С OpenSSL всё сложнее. Шифрование ГОСТ идёт с OpenSSL от версии 1.0.0 до версии 1.0.2 включительно. Но например в CentOS шифрования ГОСТ нет. Пользователи CentOS должны страдать. Для Debian, Mint, Ubuntu с OpenSSL версии 1.1.0 и выше требуется установка пакета libengine-gost-openssl1.1, поддерживаемого криптоэнтузиастом Вартаном Хачатуровым (кстати, можно ему помочь).

Ну и в 2018 году у нас есть Docker, а в Alpine Linux, как я уже упоминал, всё работает.

Как это использовать


Короткие примеры для проверки «выгрузки» Роскомнадзора с открепленной подписью. Файл «выгрузки» — dump.xml, открепленной подписи — dump.xml.sig. Даже я проверял их раньше только на целостность подписи, но не на соответствие источнику.

Используя OpenSSL:

git clone https://github.com/schors/gost-russian-ca.git ./
openssl smime -verify -engine gost         -CAfile gost-russian-ca.git/certs/ca-certificates.pem         -in dump.xml.sig -inform DER -content dump.xml  -out /dev/null

Используя LibreSSL:

git clone https://github.com/schors/gost-russian-ca.git ./
openssl smime -verify -CAfile gost-russian-ca.git/certs/ca-certificates.pem         -in dump.xml.sig -inform DER -content dump.xml  -out /dev/null

И, конечно, можно применить утилиту c_rehash в папке certs, а затем использовать опцию -CAdir вместо -CAfile.

И с этого момента можно не пользоваться сайтом Госуслуг, Контура и странными программами вроде КриптоПро для простой задачи проверки подписи. А главное, что теперь можно и автоматизировать.

Комментарии (10)


  1. ReklatsMasters
    13.09.2018 21:02

    Можно сделать ещё проще. Скомпилировать все эти алгоритмы в WASM и сделать страничку, на которой проверять все документы простым перетаскиванием.


    А если сертифицировать в ФСБ, то можно продавать серьёзным людям за деньги.


    1. schors Автор
      13.09.2018 23:00

      Это кстати отдельная интересная мысль. Например, полный ад с банк-клиентами. Но это отдельная тема с реализацией ГОСТ. Там всё на самом деле так себе. Хорошие реализации там только на языке (человечьем в смысле, все говорят «а вот мы, а вот у нас»), но в реалии даже openssl реализацию бы переработать. Есть и python, и golang, и даже java, но всё скорее акадимическое, чем продакшн реди


      1. ReklatsMasters
        13.09.2018 23:25

        Вот кстати да. Изучал этот вопрос ещё полгода назад и разочаровался. Нашёл только реализацию старого стандарта госта в nettle http://www.lysator.liu.se/~nisse/nettle/nettle.html#GOSTHASH94 более менее адекватную. Но вообще интересно, насколько это нужно тем же банкам.


        Один момент интересен в WASM, он пока не обеспечивает timing-safe. Но для цифровых подписей это вроде не критично.


  1. Newcss
    14.09.2018 09:43
    +1

    К казначейству с этими ключами подключались 3 месяца).


  1. Bessnov
    14.09.2018 09:43
    +1

    Молодец! Интересное накопал.
    Только, для кого написаны Ридми на английском языке по ссылкам на гитхабе?
    Англоязычным оно не сильно интересно будет. У них своя доверенная криптография.


    1. schors Автор
      14.09.2018 09:47

      Ответа три:
      1. Тренируюсь. У меня очень плохой английский.
      2. Вырабатываю привычку не халявить, а писать сразу для всех.
      3. Субъективно считаю, что в IT как в науке — выстрелит только то, что не огораживается. И это беда тех же ГОСТов (неплохих в теории). Это реверанс в сторону популяризации.


  1. Detuner
    14.09.2018 12:19
    +1

    Спасибо, весьма полезная статья.
    Мне постоянно приходится иметь дело с этим списком по роду деятельности. Там настоящий бардак: часть сертификатов промежуточные от корневого серта ПАК «ГУЦ», часть от ПАК «Минкомсвязь», а часть — вообще самоподписанные кросс-сертификаты. И поддерживать актуальный список сертов — это ещё полбеды. Так как не всегда и не у всех УЦ сервисы работают стабильно и быстро, нельзя полагаться на онлайн-проверку CRL. Приходится поддерживать локальное хранилище актуальных CRL — и вот это настоящая боль.


    1. schors Автор
      14.09.2018 12:33

      Хм… Это интересно. Там в XML и crl есть. Т.е. я могу в принципе буквально за вечер сделать и актуальные crl. Я только сходу не понимаю как их смотрит тот же openssl, если их отдельно делать. Не сталкивался просто


      1. Detuner
        14.09.2018 15:05
        +1

        Вот тут не знаю. Хоть и пробовал OpenSSL с ГОСТовыми алгоритмами, но эту задачу не ковырял. На проде всё завязано на криптопро, поэтому серты и CRL держу в криптопрошном хранилище. Скрипт на bash периодически качает свежие CRL, поштучно сравнивает каждый с тем, что есть в хранилище с помощью certmgr и обновляет, если скачанный CRL новее. Если по ссылкам для одного серта качаются разные CRL, выбирается самый новый. Кстати, в последнее время стали появляться УЦ, у которых списки отозванных имеют вид «base CRL + delta CRL», с ними вообще отдельная песня.
        В целом всё это работает удовлетворительно (самое узкое место — не очень быстрая работа из консоли с криптопрошным хранилищем), но есть большое желание переписать это всё на чём-то посерьёзнее bash'а и с использованием БД для хранения информации о сертах и CRL.


    1. mrandrewer
      14.09.2018 13:55
      +1

      Вот кстати да.
      Столкнулись с тем, что в самом сертификате могут быть ссылки на внутренние и недействительные адреса CRL (Это УЦ Минобороны так шутит). Но зато в XML публикуется корректный адрес. Тем и спасаемся.