Инфраструктура открытых ключей на базе российской криптографии: GnuTLS как альтернатива OpenSSL

    imageИнфраструктура открытых ключей (PKI/ИОК) включает в себя множество различных объектов и механизмов работы с ними, а также протоколы взаимодействия объектов друг с другом (например, протоколы TLS, OCSP). В число объектов ИОК входят запросы на сертификаты (PKCS#10) и сами сертификаты x509, ключевые пары (приватные и публичные ключи), подписанные и зашифрованные документы (PKCS#7, CMS), защищенные контейнеры для хранения приватных ключей (PKCS#8) и личных сертификатов с ключами (PKCS#12) и т.д. В число механизмов входят не только криптографические функции, которые позволяют шифровать и подписывать документы по различным алгоритмам, но и функции, формирующие конечные объекты ИОК в соответствии со стандартами (сертификаты, запросы, подписанные/зашифрованные документы, пакеты протоколов и т.д. и т.п.). Да, и как не вспомнить центральный объект ИОК/PKI — УЦ.

    Сегодня уже трудно представить деловую жизнь страны без ИОК, без сертификатов x509 (без квалифицированных сертификатов), без сервисов ГОСУСЛУГИ и ФНС, где документы принимаются в электронном виде с электронной подписью. И все больше документов возвращаются к гражданину тоже в электронном виде с электронной подписью. Судопроизводство уже также не возможно представить без электронной подписи.

    Наиболее продвинутым средством для создания программных средств, работающих с объектами ИОК является OpenSSL.

    OpenSSL — это набор полноценных криптографических библиотек и утилиты с открытым исходным кодом, который поддерживает почти все низкоуровневые алгоритмы хеширования, шифрования и электронной подписи, а также реализует большинство популярных криптографических стандартов. Однако в число этих криптографических стандартов не входит российская криптография. Для полноценной работы с российской криптографией в OpenSSL необходимо дополнительно подключать движок (engine) gost-engine.

    Мы уже писали, что альтернативой openssl может быть библиотека gcrypt. И вот теперь поддержка российской криптографии и криптографических механизмов реализована в проекте GnuTLS. GnuTLS поддерживает как старые криптографическе алгоритмы, так и новые — ГОСТ Р 34.10-2012 (электронная подпись), ГОСТ Р 34.11-2012 (хэширование), ГОСТ Р 34.12-2015 и ГОСТ Р 34.13-2015 (алгоритмы шифрования Кузнечик и Магма).

    По аналогии с утилитой openssl в проекте OpenSSL, в проекте GnuTLS имеется утилита certtool, которая по своим функциональным возможностям не уступает утилите openssl.

    Именно об этой утилите и её возможностях пойдет речь.

    Общие сведения об утилите certtool


    Как уже было отмечено, утилита certtool имеет много общего с утилитой openssl.

    Первым параметром утилиты certtool, как правило, идет флаг, который определяет какую функцию необходимо выполнить. Например, флаг "--certificate-info", указывает на что необходимо разобрать сертификат, а флаг "--generate-privkey" предписывает провести генерацию закрытого ключа. Входные данные, являющиеся объектами ИОК (ключи, сертификаты, списки отозванных сертификатов и т.д.), необходимые для выполнения команды, на вход поступают как ASN1-структуры в формате PEM (base64) или DER. По умолчанию используется формат PEM.

    Если данные будут поступать в формате DER, то необходимо задать опцию "--inder".

    Результатом выполнения соответствующей функции является ASN1-структура (тот же сертификат, например). По умолчанию, выходная ASN1-структура представляется в PEM-формате. Если её необходимо получить в DER-формате, то добавляется опция "--outder". Вместе с ASN1-структурой по умолчанию (опция "--text") выводится и её содержимое в текстовом виде. Если нет необходимости выводить текстовый вид, то задается опция "--no-text".

    Все это можно продемонстрировать на примере конвертации файлов с сертификатами из формата PEM в DER и наоборот:

    #Конвертация файла с сертификатом из формата PEM в DER
    #Если установлена опция --outder, то опция --no-text устанавливается по умолчанию.
    $certtool --certificate-info --infile certPEM.pem --outder --outfile certDER.der
    #Конвертация файла с сертификатом из формата DER в PEM
    $certtool --certificate-info --inder --infile certDER.der --no-text  --outfile certPEM_new.pem
    $
    

    Для получения справки по утилите certtool выполните команду:

    $certtool --help

    Справка по утилите certtool
    certtool - GnuTLS certificate tool
    Usage:  certtool [ -<flag> [<val>] | --<name>[{=| }<val>] ]...
    
       -d, --debug=num            Enable debugging
    				- it must be in the range:
    				  0 to 9999
       -V, --verbose              More verbose output
    				- may appear multiple times
           --infile=file          Input file
    				- file must pre-exist
           --outfile=str          Output file
    
    Certificate related options:
    
       -i, --certificate-info     Print information on the given certificate
           --pubkey-info          Print information on a public key
       -s, --generate-self-signed  Generate a self-signed certificate
       -c, --generate-certificate  Generate a signed certificate
           --generate-proxy       Generates a proxy certificate
       -u, --update-certificate   Update a signed certificate
           --fingerprint          Print the fingerprint of the given certificate
           --key-id               Print the key ID of the given certificate
           --v1                   Generate an X.509 version 1 certificate (with no extensions)
           --sign-params=str      Sign a certificate with a specific signature algorithm
    
    Certificate request related options:
    
           --crq-info             Print information on the given certificate request
       -q, --generate-request     Generate a PKCS #10 certificate request
    				- prohibits the option 'infile'
           --no-crq-extensions    Do not use extensions in certificate requests
    
    PKCS#12 file related options:
    
           --p12-info             Print information on a PKCS #12 structure
           --p12-name=str         The PKCS #12 friendly name to use
           --to-p12               Generate a PKCS #12 structure
    
    Private key related options:
    
       -k, --key-info             Print information on a private key
           --p8-info              Print information on a PKCS #8 structure
           --to-rsa               Convert an RSA-PSS key to raw RSA format
       -p, --generate-privkey     Generate a private key
           --key-type=str         Specify the key type to use on key generation
           --bits=num             Specify the number of bits for key generation
           --curve=str            Specify the curve used for EC key generation
           --sec-param=str        Specify the security level [low, legacy, medium, high, ultra]
           --to-p8                Convert a given key to a PKCS #8 structure
       -8, --pkcs8                Use PKCS #8 format for private keys
           --provable             Generate a private key or parameters from a seed using a provable method
           --verify-provable-privkey  Verify a private key generated from a seed using a provable method
           --seed=str             When generating a private key use the given hex-encoded seed
    
    CRL related options:
    
       -l, --crl-info             Print information on the given CRL structure
           --generate-crl         Generate a CRL
           --verify-crl           Verify a Certificate Revocation List using a trusted list
    				- requires the option 'load-ca-certificate'
    
    Certificate verification related options:
    
       -e, --verify-chain         Verify a PEM encoded certificate chain
           --verify               Verify a PEM encoded certificate (chain) against a trusted set
           --verify-hostname=str  Specify a hostname to be used for certificate chain verification
           --verify-email=str     Specify a email to be used for certificate chain verification
    				- prohibits the option 'verify-hostname'
           --verify-purpose=str   Specify a purpose OID to be used for certificate chain verification
           --verify-allow-broken  Allow broken algorithms, such as MD5 for verification
           --verify-profile=str   Specify a security level profile to be used for verification
    
    PKCS#7 structure options:
    
           --p7-generate          Generate a PKCS #7 structure
           --p7-sign              Signs using a PKCS #7 structure
           --p7-detached-sign     Signs using a detached PKCS #7 structure
           --p7-include-cert      The signer's certificate will be included in the cert list.
    				- disabled as '--no-p7-include-cert'
    				- enabled by default
           --p7-time              Will include a timestamp in the PKCS #7 structure
    				- disabled as '--no-p7-time'
           --p7-show-data         Will show the embedded data in the PKCS #7 structure
    				- disabled as '--no-p7-show-data'
           --p7-info              Print information on a PKCS #7 structure
           --p7-verify            Verify the provided PKCS #7 structure
           --smime-to-p7          Convert S/MIME to PKCS #7 structure
    
    Other options:
    
           --get-dh-params        List the included PKCS #3 encoded Diffie-Hellman parameters
           --dh-info              Print information PKCS #3 encoded Diffie-Hellman parameters
           --load-privkey=str     Loads a private key file
           --load-pubkey=str      Loads a public key file
           --load-request=str     Loads a certificate request file
           --load-certificate=str Loads a certificate file
           --load-ca-privkey=str  Loads the certificate authority's private key file
           --load-ca-certificate=str Loads the certificate authority's certificate file
           --load-crl=str         Loads the provided CRL
           --load-data=str        Loads auxiliary data
           --password=str         Password to use
           --null-password        Enforce a NULL password
           --empty-password       Enforce an empty password
           --hex-numbers          Print big number in an easier format to parse
           --cprint               In certain operations it prints the information in C-friendly format
           --hash=str             Hash algorithm to use for signing
           --salt-size=num        Specify the RSA-PSS key default salt size
           --inder                Use DER format for input certificates, private keys, and DH parameters
    				- disabled as '--no-inder'
           --inraw                an alias for the 'inder' option
           --outder               Use DER format for output certificates, private keys, and DH parameters
    				- disabled as '--no-outder'
           --outraw               an alias for the 'outder' option
           --template=str         Template file to use for non-interactive operation
           --stdout-info          Print information to stdout instead of stderr
           --ask-pass             Enable interaction for entering password when in batch mode.
           --pkcs-cipher=str      Cipher to use for PKCS #8 and #12 operations
           --provider=str         Specify the PKCS #11 provider library
           --text                 Output textual information before PEM-encoded certificates, private
    keys, etc
    				- disabled as '--no-text'
    				- enabled by default
    
    Version, usage and configuration options:
    
       -v, --version[=arg]        output version information and exit
       -h, --help                 display extended usage information and exit
       -!, --more-help            extended usage information passed thru pager
    
    Options are specified by doubled hyphens and their name or by a single
    hyphen and the flag character.
    
    Tool to parse and generate X.509 certificates, requests and private keys.
    It can be used interactively or non interactively by specifying the
    template command line option.
    
    The tool accepts files or supported URIs via the --infile option.  In case
    PIN is required for URI access you can provide it using the environment
    variables GNUTLS_PIN and GNUTLS_SO_PIN.
    
    Please send bug reports to:  <[email protected]>
    


    Теперь переходим к основным функциям утилиты certtool

    Генерация и просмотр пары


    Для генерации закрытого ключа по алгоритму ГОСТ Р 34.10 2012 используется следующая команда:

    $certtool --generate-privkey --key-type [gost12-256 | gost12-512] --curve <значение параметра> [--no-text] [--outder] [--outfile <имя файла для ключа>]
    $

    Криптопараметры (--curve) при генерации ключевой пары задаются OID-ами. В настоящее время TK-26 определил следующие oid-ы для криптопараметров алгоритма подписи ГОСТ Р 34.10-2012 с ключом 256:

    1.2.643.7.1.2.1.1.1 (id-tc26-gost-3410-12-256-paramSetA) [TC26-256-A];
    1.2.643.7.1.2.1.1.2 (id-tc26-gost-3410-12-256-paramSetB) [TC26-256-B];
    1.2.643.7.1.2.1.1.3 (id-tc26-gost-3410-12-256-paramSetC) [TC26-256-C];
    1.2.643.7.1.2.1.1.4 (id-tc26-gost-3410-12-256-paramSetD) [TC26-256-D].

    При этом продолжают действовать так называемые OID-ы параметров от КриптоПро:

    1.2.643.2.2.35.1 (id-GostR3410-2001-CryptoPro-A-ParamSet) [CryptoPro-A];
    1.2.643.2.2.35.2 (d-GostR3410-2001-CryptoPro-B-ParamSet) [CryptoPro-B];
    1.2.643.2.2.35.3 (id-GostR3410-2001-CryptoPro-C-ParamSet) [CryptoPro-C];
    1.2.643.2.2.36.0 (id-GostR3410-2001-CryptoPro-XchA-ParamSet) [CryptoPro-XchA];
    1.2.643.2.2.36.1 (id-GostR3410-2001-CryptoPro-XchB-ParamSet) [CryptoPro-XchB].

    Напомним, что параметры КриптоПро с OID-ами 1.2.643.2.2.35.1, 1.2.643.2.2.35.2, 1.2.643.2.2.35.3 соответствуют параметрам ТК-26 с OID-ами 1.2.643.7.1.2.1.1.1, 1.2.643.7.1.2.1.1.2, 1.2.643.7.1.2.1.1.3 соответственно.

    С криптопараметрами для алгоритма подписи ГОСТ Р 34.10-2012 с ключом 512 проще:

    1.2.643.7.1.2.1.2.1 (id-tc26-gost-3410-2012-512-paramSetA) [TC26-512-A];
    1.2.643.7.1.2.1.2.2 (id-tc26-gost-3410-2012-512-paramSetB) [TC26-512-B];
    1.2.643.7.1.2.1.2.3 (id-tc26-gost-3410-2012-512-paramSetC) [TC26-512-C];

    В GnuTLS введены свои обозначения для криптопараметров и они указаны в квадратных скобках, например [TC26-256-B]. К сожалению, при генерации ключа криптопараметры можно задать только их символьным обозначением. OID-ы в точечно-цифровой форме отвергаются.
    Но это не самый большой недостаток. В настоящее время в GnuTLS поддерживаются только два криптопараметра. Для ключей ГОСТР 34.10-2012-256 (опция --key-type gost12-256) это параметр с oid-ом 1.2.643.7.1.2.1.1.2 (опция --curve TC26-256), а для ключей длиною 512 бит это параметр с oid-ом 1.2.643.7.1.2.1.2.1 (опция --curve TC26-512-A).

    Итак, создаем закрытый ключ (флаг --generate-privkey) и просматриваем информацию о ключе (флаг --key-info):

    #Создаём закрыты ключ  --key-type gost12-256 --curve TC26-256-B
    $certtool --generate-privkey --key-type gost12-256 --curve TC26-256-B --no-text --outder --outfile key256.der
    Generating a 256 bit GOST R 34.10-2012-256 private key (TC26-256-B)...
    #Смотрим ключевую пару
    $certtool --key-info --inder --infile key256.der
    Public Key Info:
       Public Key Algorithm: GOST R 34.10-2012-256
       Key Security Level: High (256 bits)
    
    curve:   TC26-256-B
    digest:  STREEBOG-256
    paramset:   TC26-Z
    private key:
       4b:df:cb:9e:cc:49:c5:a2:70:36:c9:d8:df:55:97:f5
       8b:be:ae:06:7b:34:76:39:b6:aa:57:af:3f:2d:98:36
    x:
       0d:71:29:56:d2:39:59:6f:14:d3:4b:75:44:85:91:a9
       5d:fa:83:4a:93:9a:2c:20:b0:6b:5c:74:8c:76:5f:a5
    y:
       2d:ac:da:23:f3:2f:45:d9:47:c4:a3:c1:d7:65:bd:46
       1d:ba:12:cd:15:e1:b0:8f:5a:99:f2:35:ea:fc:33:fc
       
    Public Key PIN:
       pin-sha256:nrftlmdCrSf11N+ivohfuGXSQixa4Scnhl7GTsUTE2E=
    Public Key ID:
       sha256:9eb7ed966742ad27f5d4dfa2be885fb865d2422c5ae12727865ec64ec5131361
       sha1:25927018f3775ed86996c625a99b7db86b2d0a7e
    -----BEGIN PRIVATE KEY-----
    MEACAQAwFwYIKoUDBwEBAQEwCwYJKoUDBwECAQECBCIEIDaYLT+vV6q2OXY0ewau
    vov1l1Xf2Mk2cKLFScyey99L
    -----END PRIVATE KEY-----
    $

    В информации о ключе мы имеем полную информацию как о приватном (закрытом) ключе, включая его asn1-структуру, так и публичном ключе, включая его значение (x и y).
    Теперь посмотрим на asn1-структуру приватного ключа. Для этого воспользуемся утилитой cryptoarmpkcs:



    В этой структуре вы не найдете значения открытого ключа. Значение открытого ключа вычисляется через закрытый ключ. А вот закрытый ключ по открытому вычислить, естественно, нельзя!!! И всё же досадно, что asn1-структура публичного ключа не доступна при просмотре приватного ключа (флаг --key-info). Можно было бы ввести опцию --pubkey-info (такая опция есть для сертификата), по которой бы выводилась asn1-структура открытого ключа.

    Конечно, приватный ключ надо хранить надежно, по крайней мере зашифрованным на пароле. Для безопасного хранения приватного ключа используется контейнер PKCS8, который предоставляет возможность шифрования закрытого ключа с помощью шифрования на основе пароля пользователя. Поскольку здесь речь идет об использовании российской криптографии и рекомендаций ТК-26, то команда генерации закрытого ключа в защищенном контейнере PKCS8, будет иметь вид:

    $certtool --generate-privkey --pkcs8 --pkcs-cipher gost28147-tc26z [--password <пароль>] --key-type [gost12-256 | gost12-512] --curve <значение параметра> [--no-text] [--outder] [--outfile <имя файла для ключа>]
    $

    Если опция "--password" не задана, то пароль для шифрования закрытого ключа будет запрошен в командной строке:

    bash-5.1$ ./generate_key_parse_password.sh 
    #Создаём закрытый ключ  --key-type gost12-256 --curve TC26-256-B
    $certtool --generate-privkey --pkcs8 --pkcs-cipher gost28147-tc26z --password 01234567  --key-type gost12-256 --curve TC26-256-B --no-text --outder --outfile key256_pkcs8.der
    Generating a 256 bit GOST R 34.10-2012-256 private key (TC26-256-B)...
    #Смотрим информацию о ключе
    $certtool --key-info --inder --infile key256.der
    Encrypted structure detected...
    Enter password: <ВВОД ПАРОЛЯ>
    PKCS #8 information:
       Cipher: GOST28147-TC26Z-CFB
       Schema: PBES2-GOST28147-89-TC26Z (1.2.643.7.1.2.5.1.1)
       Salt: 32b2798c23a5d0ab8c3144daf273745bdb
       Salt size: 17
       Iteration count: 5333
    
    Public Key Info:
       Public Key Algorithm: GOST R 34.10-2012-256
       Key Security Level: High (256 bits)
    
    curve:   TC26-256-B
    digest:  STREEBOG-256
    paramset:   TC26-Z
    private key:
       05:20:c3:7a:93:a2:e1:b4:64:50:a4:fb:db:cc:74:43
       1a:14:d9:00:c4:82:dc:f5:94:8a:8a:65:a4:76:47:76   
    x:
       1b:3e:0b:e0:3b:fc:1d:ee:62:10:63:66:72:fc:66:a6
       d5:b8:94:b1:fe:a4:ec:d6:d8:f1:18:63:95:a9:30:15   
    y:
       fb:c0:24:10:41:12:98:7f:aa:15:cd:3b:7e:e7:64:bd
       c4:97:3d:18:04:82:f0:80:61:8e:ff:48:eb:d6:97:d5  
    Public Key PIN:
       pin-sha256:eD6s4BQl4R0WY6H8KJZKDA6zuzd6A7JcNCh4FpUH1Rg=
    Public Key ID:
       sha256:783eace01425e11d1663a1fc28964a0c0eb3bb377a03b25c342878169507d518
       sha1:62afc2d7c8bf77f1ac0820324170cd2262a63091
    
    -----BEGIN PRIVATE KEY-----
    MEACAQAwFwYIKoUDBwEBAQEwCwYJKoUDBwECAQECBCIEIHZHdqRlioqU9dyCxADZ
    FBpDdMzb+6RQZLThopN6wyAF
    -----END PRIVATE KEY-----
    #Смотрим закрытый ключ средствами openssl и сравниваем
    /usr/local/lirssl_csp_64/bin/lirssl pkcs8 -inform DER -in key256_pkcs8.der  -outform PEM
    -----BEGIN PRIVATE KEY-----
    MEACAQAwFwYIKoUDBwEBAQEwCwYJKoUDBwECAQECBCIEIHZHdqRlioqU9dyCxADZ
    FBpDdMzb+6RQZLThopN6wyAF
    -----END PRIVATE KEY-----
    bash-5.1$  

    Создание запроса на сертификат


    Имея закрытый ключ, можно приступить к созданию запроса на сертификат.

    Для создания запроса используется флаг --generate-request:

    certtool --generate-request --load-privkey <файл с приватным ключом> --template <файл с шаблоном запроса> [--no-text]
    

    Рассмотрим создание запроса на сертификат для физического лица. Сертификат планируется использовать для формирования и проверки электронной подписи. В этом случае файл с шаблоном запроса может содержать только отличительное имя (DN — distinguished name) владельца сертификата, которое включает следующие типы атрибутов/oid-ов и их значения:

    #Страна - oid=2.5.4.6
    #country = RU
    #Альтернативный способ
    dn_oid = "2.5.4.6 RU"
    #Субъект - 2.5.4.8
    state = "50 Московская олбласть"
    #Альтернативный способ
    #dn_oid = "2.5.4.6 RU"
    #Местность, город - 2.5.4.7
    locality = "г. Козельск"
    #Адрес - 2.5.4.9
    #street = "Вот моя деревня, вот мой дом родной"
    #Альтернативный способ
    #dn_oid = "2.5.4.9 Вот моя деревня, вот мой дом родной"
    #Организация - 2.5.4.10
    #organization = "Рога и копыта"
    #Фамилия surname 2.5.4.4
    #sn = "Хабр"
    dn_oid = "2.5.4.4 Балаганов"
    #Имя, отчество givenname - 2.5.4.42
    #ginenName = "Алесандр Остапович"
    dn_oid = "2.5.4.42 Алесандр Остапович"
    #Общепринятое имя commonName - 2.5.4.3
    cn = "Балаганов Шура"
    

    Как видно из шаблона, атрибуты для DN (отличительного имени) могут задаваться как с использованием символьного имени атрибута, принятого в GnuTLS (например, country = RU), так и использованием oid-а атрибута:

    dn_oid = "<oid атрибута> <значение атрибута>"
    .
    В этом случае, указать страну можно и так:

    dn_oid = "2.5.4.6 RU"

    Если мы хотим, чтобы отличительное имя в запросе учитывало «Требования к форме квалифицированного сертификата ключа проверки электроннойподписи», то придется добавить в него еще и ИНН и СНИЛС, если речь идет о физическом лице:

    #Индивидуальный Номер Налогоплательщика - ИНН/INN
    dn_oid = "1.2.643.3.131.1.1  123456789012"
    #Страховой Номер Индивидуального Лицевого Счёта - СНИЛС/SNILS
    dn_oid = "1.2.643.100.3 12345678901"

    Итак, пусть закрытый ключ хранится в файле privkey.pem, а шаблон — в файле templateP10.txt. Тогда запрос может быть сформирован и просмотрен следующей командой:

    $certtool --generate-request --load-privkey privkey.pem --template templateP10.txt
    Generating a PKCS #10 certificate request...
    PKCS #10 Certificate Request Information:
       Version: 1
       Subject: [email protected],SNILS=12345678909,INN=123456789098,givenName=сын лейтенанта Шмидта,surName=Балаганов,street=Вот моя деревня\, вот мой дом родной,C=RU,ST=Московская область,L=г. Козельск,CN=Шура Балаганов
       Subject Public Key Algorithm: GOST R 34.10-2012-256
       Algorithm Security Level: High (256 bits)
          Curve:   TC26-256-B
          Digest:  STREEBOG-256
          ParamSet: TC26-Z
          X:
             23:63:5c:72:6f:ac:bb:76:59:a6:65:d0:45:9b:29:ad
             3c:87:59:15:52:21:e2:91:5c:ca:da:16:3e:b9:f7:fa
          Y:
             4d:84:a0:79:a4:02:d4:20:b4:01:e6:4c:9b:da:5e:6a
             4a:cd:b4:7e:c0:01:7e:8d:29:0c:f4:a6:d7:b3:07:a0
       Signature Algorithm: GOSTR341012-256
       Attributes:
          Extensions:
             Subject Signing Tool(not critical):
                GnuTLS
             Basic Constraints (critical):
                Certificate Authority (CA): FALSE
             Key Usage (critical):
                Digital signature.
    Other Information:
       Public Key ID:
          sha1:c0e53bf1cc35f14dce4b7e05ee091c90f497dadf
          sha256:eb3dc1375ea60f165b51a9349b32a1a4eab1614e5d49fd02bdf66785095984ea
       Public Key PIN:
          pin-sha256:6z3BN16mDxZbUak0mzKhpOqxYU5dSf0CvfZnhQlZhOo=
    
    Self signature: verified
    
    -----BEGIN NEW CERTIFICATE REQUEST-----
    MIICajCCAhcCAQAwggFrMSQwIgYDVQQDDBvQqNGD0YDQsCDQkdCw0LvQsNCz0LDQ
    vdC+0LIxHTAbBgNVBAcMFNCzLiDQmtC+0LfQtdC70YzRgdC6MSwwKgYDVQQIDCPQ
    nNC+0YHQutC+0LLRgdC60LDRjyDQvtCx0LvQsNGB0YLRjDELMAkGA1UEBhMCUlUx
    SDBGBgNVBAkMP9CS0L7RgiDQvNC+0Y8g0LTQtdGA0LXQstC90Y8sINCy0L7RgiDQ
    vNC+0Lkg0LTQvtC8INGA0L7QtNC90L7QuTEbMBkGA1UEBAwS0JHQsNC70LDQs9Cw
    0L3QvtCyMTEwLwYDVQQqDCjRgdGL0L0g0LvQtdC50YLQtdC90LDQvdGC0LAg0KjQ
    vNC40LTRgtCwMRowGAYIKoUDA4EDAQESDDEyMzQ1Njc4OTA5ODEWMBQGBSqFA2QD
    EgsxMjM0NTY3ODkwOTEbMBkGCSqGSIb3DQEJARYMZ251dGxzQGFhLnJ1MF4wFwYI
    KoUDBwEBAQEwCwYJKoUDBwECAQECA0MABED697k+FtrKXJHiIVIVWYc8rSmbRdBl
    pll2u6xvclxjI6AHs9em9AwpjX4BwH60zUpqXtqbTOYBtCDUAqR5oIRNoEMwQQYJ
    KoZIhvcNAQkOMTQwMjARBgUqhQNkbwQIDAZHbnVUTFMwDAYDVR0TAQH/BAIwADAP
    BgNVHQ8BAf8EBQMDB4AAMAoGCCqFAwcBAQMCA0EARPHu9P2dPb2GrhQTeOBkmbA0
    Fw5I0HDF1S5YI7g0jJmdz70rv80XpozmkNKpARN9yYQx9t82fUXUGqwJK9A4RA==
    -----END NEW CERTIFICATE REQUEST-----
    
    $ 

    Сохраним запрос на сертификат в файле request.pem, и отправимся с ним в УЦ за сертификатом.
    Справедливости ради, стоит отметить, что утилита certtool имеет большие возможности по формирования не только запросов на сертификат, так и самих сертификатов. Эти возможности ничем не уступают возможностям ни openssl ни nss.

    Получение, просмотр и проверка сертификатов


    Для выпуска сертификата всё же воспользуемся утилитой CAFL63:



    Предположим, что выданный сертификат хранится в файле certfromreq.pem. Вместе с сертификатом пользователи, как правило, получают и сертификат самого удостоверяющего центра, т.е. сертификат, закрытым ключом которого подписан полученный сертификат. Наличие сертификата УЦ позволяет проверить пользовательский сертификат:
    $certtool --verify --verify-profile normal   [--inder] --load-ca-certificate <файл с сертификатом УЦ> --infile <файл с сертификатом пользователя>

    Например, есть пользовательский сертификат сохранен в файле certfromreq.pem, а сертификат УЦ в файле rootca_12_256_TC26.pem, то для проверки достаточно выполнить следующую команду:

    bash-5.1$ certtool --verify --verify-profile normal  --load-ca-certificate rootca_12_256_TC26.pem  --infile certfromreq.pem 
    Loaded CAs (1 available)
            Subject: [email protected],SNILS=12345678909,INN=123456789098,givenName=сын лейтенанта Шмидта,surName=Балаганов,street=Вот моя деревня\, вот мой дом родной,C=RU,ST=Московская область,L=г. Козельск,CN=Шура Балаганов
            Issuer: [email protected],OGRN=1234567890123,INN=001234567890,CN=Тестовый УЦ CAFL63,OU=Удостоверяюший Центр,O=Тестовый УЦ CAFL63,street=ул. Ленинская\, д. 4,L=г. Юбилейный,ST=Московская область,C=RU
            Checked against: [email protected],OGRN=1234567890123,INN=001234567890,CN=Тестовый УЦ CAFL63,OU=Удостоверяюший Центр,O=Тестовый УЦ CAFL63,street=ул. Ленинская\, д. 4,L=г. Юбилейный,ST=Московская область,C=RU
            Signature algorithm: GOSTR341012-256
            Output: Verified. The certificate is trusted. 
    
    Chain verification output: Verified. The certificate is trusted. 
    
    bash-5.1$

    Для просмотра полученного сертификата нужно воспользоваться флагом --certificate-info:

    bash-5.1$ certtool --certificate-info --infile CertFromReqGnuTLS_2.pem 

    X.509 Certificate Information:
    
       Version: 3
       Serial Number (hex): 1022
       Issuer: [email protected],OGRN=1234567890123,INN=001234567890,CN=Тестовый УЦ CAFL63,OU=Удостоверяюший Центр,O=Тестовый УЦ CAFL63,street=ул. Ленинская\, д. 4,L=г. Юбилейный,ST=Московская область,C=RU
       Validity:
          Not Before: Tue Apr 27 11:50:00 UTC 2021
          Not After: Thu Apr 28 11:50:00 UTC 2022
       Subject: [email protected],SNILS=12345678909,INN=123456789098,givenName=сын лейтенанта Шмидта,surName=Балаганов,street=Вот моя деревня\, вот мой дом родной,C=RU,ST=Московская область,L=г. Козельск,CN=Шура Балаганов
       Subject Public Key Algorithm: GOST R 34.10-2012-256
       Algorithm Security Level: High (256 bits)
          Curve:   TC26-256-B
          Digest:  STREEBOG-256
          ParamSet: TC26-Z
          X:
             23:63:5c:72:6f:ac:bb:76:59:a6:65:d0:45:9b:29:ad
             3c:87:59:15:52:21:e2:91:5c:ca:da:16:3e:b9:f7:fa
          Y:
             4d:84:a0:79:a4:02:d4:20:b4:01:e6:4c:9b:da:5e:6a
             4a:cd:b4:7e:c0:01:7e:8d:29:0c:f4:a6:d7:b3:07:a0
       Extensions:
          Basic Constraints (critical):
             Certificate Authority (CA): FALSE
          Issuer Signing Tool(not critical):
             SignTool: СКЗИ ЛИРССЛ-CSP
             CATool: Тестовый УЦ CAFL63
             SignToolCert: № СФ-124/3917  от 29 сентября 2020 г.
             CAToolCert: Сертификат УЦ №
          Subject Signing Tool(not critical):
             GnuTLS
          Certificate Policies (not critical):
             1.2.643.100.113.1 (Russian security class KC1)
             1.2.643.100.113.2 (Russian security class KC2)
          Key Usage (not critical):
             Digital signature.
          Key Purpose (not critical):
             1.2.643.6.3.1.2.2
             TLS WWW Client.
             Email protection.
             1.3.6.1.4.1.311.20.2.2
             1.2.643.5.1.28.2
             1.2.643.5.1.28.3
             TLS WWW Client.
             Email protection.
          Subject Key Identifier (not critical):
             ddc80c1857a797dd540b70825e251c2180f585d5
          Authority Key Identifier (not critical):
             directoryName: [email protected],OGRN=1234567890123,INN=001234567890,CN=Тестовый УЦ CAFL63,OU=Удостоверяющий Центр,O=Тестовый УЦ CAFL63,street=ул. Ленинская\, д. 4,L=г. Юбилейный,ST=Московская область,C=RU
             serial: 00c79588557040f04e
             70c016b99db59d8466316ea4a51ee0d1026b5cfe
          Subject Alternative Name (not critical):
             RFC822Name: [email protected]
          Issuer Alternative Name (not critical):
          Authority Information Access (not critical):
             Access Method: 1.3.6.1.5.5.7.48.2 (id-ad-caIssuers)
             Access Location URI: http://museum.lissi-crypto.ru/docs/ucfz_63/CAFL63.crt
       Signature Algorithm: GOSTR341012-256
       Signature:
          0b:51:a3:d9:77:9f:9e:7d:91:e0:d8:4d:d9:82:a9:71
          91:be:82:ee:5a:6c:c6:79:af:34:1d:30:69:d1:ae:4f
          a5:79:18:6d:46:08:8c:44:65:6f:2c:24:74:8c:09:7f
          30:52:dc:65:9c:f9:b6:46:81:14:a9:83:2a:c0:80:d3
    Other Information:
       Fingerprint:
          sha1:d53b007e3d1c3880cb7f92b7e29263cf9c5605c3
          sha256:14bbeeeaeb4219147048dae551eceb2e62de5d00571c6c0ee862161ca2260755
       Public Key ID:
          sha1:c0e53bf1cc35f14dce4b7e05ee091c90f497dadf
          sha256:eb3dc1375ea60f165b51a9349b32a1a4eab1614e5d49fd02bdf66785095984ea
       Public Key PIN:
          pin-sha256:6z3BN16mDxZbUak0mzKhpOqxYU5dSf0CvfZnhQlZhOo=
    
    -----BEGIN CERTIFICATE-----
    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
    fzBS3GWc+bZGgRSpgyrAgNM=
    -----END CERTIFICATE-----
    
    bash-5.1$

    А если вместо флага --certificate-info указать флаг --pubkey--info, то мы получим не тольно информацию о публичном ключе, но и его asn1-структуру:
    bash-5.1$ certtool --pubkey-info  --infile CertFromReqGnuTLS_2.pem |expand -3
    Public Key Information:
       Public Key Algorithm: GOST R 34.10-2012-256
       Algorithm Security Level: High (256 bits)
          Curve:   TC26-256-B
          Digest:  STREEBOG-256
          ParamSet: TC26-Z
          X:
             23:63:5c:72:6f:ac:bb:76:59:a6:65:d0:45:9b:29:ad
             3c:87:59:15:52:21:e2:91:5c:ca:da:16:3e:b9:f7:fa
          Y:
             4d:84:a0:79:a4:02:d4:20:b4:01:e6:4c:9b:da:5e:6a
             4a:cd:b4:7e:c0:01:7e:8d:29:0c:f4:a6:d7:b3:07:a0
    Public Key Usage:
       Digital signature.
       Key encipherment.
       Key agreement.
    Public Key ID:
       sha1:c0e53bf1cc35f14dce4b7e05ee091c90f497dadf
       sha256:eb3dc1375ea60f165b51a9349b32a1a4eab1614e5d49fd02bdf66785095984ea
    Public Key PIN:
       pin-sha256:6z3BN16mDxZbUak0mzKhpOqxYU5dSf0CvfZnhQlZhOo=
    #ASN1-структура публичного ключа в PEM-формате
    -----BEGIN PUBLIC KEY-----
    MF4wFwYIKoUDBwEBAQEwCwYJKoUDBwECAQECA0MABED697k+FtrKXJHiIVIVWYc8
    rSmbRdBlpll2u6xvclxjI6AHs9em9AwpjX4BwH60zUpqXtqbTOYBtCDUAqR5oIRN
    -----END PUBLIC KEY-----
    bash-5.1$

    Теперь, когда есть сертификат и его закрытый ключ, а также сертификат УЦ, можно их все вместе положить в один защищенный контейнер PKCS#12.

    Работа с защищенным контейнером PKCS#12


    Работая с российской криптографией, при создании защищенного контейнера PKCS#12, естественно, руководствоваться Рекомендациями ТК-26, описывающими формирование транспортных ключевых контейнеров для ключей, созданных в соответствии с ГОСТ Р 34.10.

    Исходя из этого, команда создания контейнера PKCS#12 будет выглядеть следующим образом:

    certtool --to-p12  --pkcs-cipher=gost28147-tc26z --hash streebog-512 [--inder] [--ask-pass | --password <пароль для контейнера>]  [--p12-name "<friendly name>"]  --load-certificate <файл с сертификатом> --load-privkey <файл с закрытым ключом сертификата>  --load-ca-certificate <файл с сертификатом УЦ> [--outder] [--outfile <имя файля для контейнера>]
    

    Отметим, что если не заданы опции --password и/или --p12-name, то они будут запрошены в командной строке.

    Создадим контейнер PKCS#12:

    $ certtool --to-p12  --pkcs-cipher=gost28147-tc26z --hash streebog-512  --load-certificate certUser.pem  --load-privkey privkeyUser.pem  --load-ca-certificate certCA.pem --p12-name "TectP12GnuTLS" --password "01234567"        
    Generating a PKCS #12 structure...
    Loading private key list...
    Loaded 1 private keys.
    Контейнер PKCS#12 в PEM-формате
    -----BEGIN PKCS12-----
    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
    -----END PKCS12-----
    bash-5.1$

    Надо отметить, что сегодня защищенный контейнер PKCS#12 пользуется популярностью.
    Контейнер PKCS#12, созданный утилитой certtool, успешно был разобран утилитой openssl с поддержкой ГОСТ. После этого решили воспользоваться утилитой cryptoarmpkcs, которая позволяет извлекать из контейнера PKCS#12 сертификат и его закрытый ключ и устанавливать их на токен PKCS#11, а также, используя сам контейнер, подписывать документы.

    И тут пришлось столкнуться с неприятным сюрпризом:



    Сюрприз заключается в том, что, при создании контейнера PKCS#12, GnuTLS не учитывает последние требования ТК-26, которые гласят:

    Целостность ТКК обеспечивается с использованием алгоритма HMAC_GOSTR3411_2012_512 в соответствии с Р 50.1.113— 2016.

    Утилита certtool использует алгоритм HMAC_GOSTR3411_2012_256, который жестко зашит в код библиотеки. Но это легко устранимый баг. Для этого достаточно в функции _gnutls_pkcs_generate_key (файл ~/gnutls-xxx/lib/x509/pkcs7-crypt.c) поменять строку

    kdf_param->mac = GNUTLS_MAC_STREEBOG_256;
    на строку
    kdf_param->mac = GNUTLS_MAC_STREEBOG_512;

    После внесения этой правки всё встало на свои места и контейнер PKCS#12 от GnuTLS был принят утилитой cryptoarmpkcs:



    Приведенный выше пример контейнера PKCS#12 (-----BEGIN PKCS12-----… -----END PKCS12-----) сформирован с учётом требований ТК-26.

    Итак, имея контейнер PKCS#12 и утилиту cryptoarmpkcs можно формировать различные виды подписи для документов (см. скриншот). Но нас сейчас интересует формирование электронной подписи утилитой certtool.

    Электронная подпись PKCS#7


    Команда формирования электронной подписи выглядит следующим образом:

    $certtool --p7-sign [--p7-time] [--inder] --load-privkey <файл с закрытым ключом> --load-certificate <файл с сертификатом> --infile <файл с документом> [--outder] [--outfile <файл для подписи>]

    Пояснения требует только опция --p7-time, наличие которой предписывает включать в саму подпись (структуру PKCS#7) время формирования электронной подписи.

    Кстати, для тестирования формирования электронной подписи сертификат и его закрытый ключ можно взять из контейнера PKCS#12, приведенного в предыдущем разделе:

    $certtool --p12-info --no-text --infile <файл, где вы сохранили контейнер PKCS#12>

    Если сертификат пользователя закрытый ключ был сохранён в файле privkey.pem, а сертификат пользователя в файле usercert.pem, то подписание документа из файла doc.txt с сохранением подписи в файле signdoc.sig будет выглядеть так:

    $certtool --p7-sign --loadcertificate usercert.pem --load-privkey privkey.pem --infile doc.txt --outfile signdoc.sig
    Enter password
    $

    Если подпись присоединённая (а по умолчанию именно она и создаётся), то извлечь подписанный документ можно следующей командой:

    $certtool --p7-info --p7-show-data [--inder] --infile <файл с ЭП>
    

    Для просмотра информации об электронной подписи используется флаг --p7-info:

    $certtool --p7-info [--inder] 

    Для проверки самой электронной подписи необходим сертификат подписанта:

    $certtool --p7-verify [--inder] --load-certificate <файл с сертификатом подписанта> --infile <файл с электронной подписью>
    

    Да, для формирования отсоединенной подписи используется опция --p7-detached-sign

    Послесловие


    Я не ставил целью дать полное описание утилиты certtool и тем более написать документацию по GnuTLS. Это авторы и без меня хорошо сделали.

    Цель была показать, что есть такое средство как GnuTLS и его можно использовать наряду с OpenSSL или GCrypt для работы с ИОК на базе российской криптографии. Насколько это удалось, судить читателю.

    Средняя зарплата в IT

    120 000 ₽/мес.
    Средняя зарплата по всем IT-специализациям на основании 7 078 анкет, за 1-ое пол. 2021 года Узнать свою зарплату
    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 0

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое