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

    Приближается вторая половина 2018 года и скоро должен наступить «2000-й год» в ИОК на базе российской криптографии. Это связано с тем, что
    использование схемы подписи ГОСТ Р 34.10-2001 для формирования подписи после 31 декабря 2018 года не допускается!
    Уже сегодня не имеет смысла получать сертификаты с подписью по ГОСТ Р 34.10-2001.
    В то же время очень много сервисов или приложений разработано на базе OpenSSL, который поддерживал работу с ГОСТ Р 34.10-2001.

    Но сегодня в стандартной версии openssl отсутствует поддержка как ГОСТ Р 34.11-2012, так и ГОСТ Р 34.10-2012. Более того, в версии 1.1 поддержка криптографии ГОСТ исключена из стандартной поставки («The GOST engine was out of date and therefore it has been removed.»).

    Все это заставляет искать альтернативные пути для работы с сертификатами, с электронной подписью («сообщениями формата CMS») и другими объектами ИОК на базе новой российской криптографии.

    Одним из таких возможных путей является использование библиотеки GCrypt. В этой библиотеке реализована поддержка новых алгоритмов ГОСТ Р 34.11-2012 (алгоритмы хэширования) и ГОСТ Р 34.10-2012 (алгоритмы подписи).

    Генерация ключевой пары


    Итак, начинаем с генерации ключевой пары, содержащей как закрытый, так и открытый ключи. На данный момент в российской криптографии присутствует три типа ключей подписи с соответствующими oid-ами
    — ГОСТ Р 34.10-2001 с длиной ключа 256 бит, oid 1.2.643.2.2.19 (0x2a, 0x85, 0x03, 0x02, 0x02, 0x13);
    — ГОСТ Р 34.10-2012 с длиной ключа 256 бит (далее ГОСТ Р 34.10-12-256), oid 1.2.643.7.1.1.1.1 (0x2a, 0x85, 0x03, 0x07, 0x01, 0x01, 0x01, 0x01);
    — ГОСТ Р 34.10-2012 с длиной ключа 512 бит (далее ГОСТ Р 34.10-12-512), oid 1.2.643.7.1.1.1.2 (0x2a, 0x85, 0x03, 0x07, 0x01, 0x01, 0x01, 0x02).
    И сразу отметим, что в части математики, алгоритмов генерации и их реализации, ключи ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-12-256 абсолютно идентичны! Так же как идентичны алгоритмы формирования электронной подписи на их основе. О каком из этих ключей идет речь можно судить только по информации о ключе, содержащейся, например, в сертификате. Так зачем потребовалось два разных oid-а? Только подчеркнуть тот факт, что при формировании электронной подписи с ключом ГОСТ Р 34.10-2001 должен использоваться хэш, полученный по ГОСТ Р 34.10-94, а при использовании ключа ГОСТ Р 34.10-12-256 должен использоваться хэш, получаемый по ГОСТ Р 34.10-212 с длиной 256 бит. Хотя, чтобы подчеркнуть это, есть оказывается соответствующие oid-ы:
    — 1.2.643.2.2.3 (0x2a, 0x85, 0x03, 0x02, 0x02, 0x03) — алгоритм подписи ГОСТ Р 34.10-2001 с ключом 256 с хэшированием ГОСТ Р 34.11-94;
    — 1.2.643.7.1.1.3.2 (0x2a, 0x85, 0x03, 0x07, 0x01, 0x01, 0x03, 0x02) — алгоритм подписи ГОСТ Р 34.10-2012 с ключом 256 с хэшированием ГОСТ Р 34.11-2012;
    — 1.2.643.7.1.1.3.3 (0x2a, 0x85, 0x03, 0x07, 0x01, 0x01, 0x03, 0x03) — алгоритм подписи ГОСТ Р 34.10-2012 с ключом 512 с хэшированием ГОСТ Р 34.11-2012.
    Таким образом, имеется некоторый перебор с oid-ами, но что есть, то есть.

    Ключи семейства ГОСТ относятся к семейству ключей на эллиптических кривых. Для генерации ключевой пары необходимо указать базовую точку на эллиптической кривой.

    Техническим комитетом по стандартизации «Криптографическая защита информации» (ТК 26) рекомендованы для использования две базовые точки для ключей ГОСТ Р 34.10-2012-512:
    — GOST2012-tc26-A (nickname в терминологии libgcrypt) с oid-ом 1.2.643.7.1.2.1.2.1 (0x2a, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x01);
    — GOST2012-tc26-B с oid-ом 1.2.643.7.1.2.1.2.2 (0x2a, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x02);
    Для ключей ГОСТ Р 34.10 с длиной 256 бит рекомендованы три базовые точки:
    — GOST2001-CryptoPro-A с oid-ом 1.2.643.2.2.35.1 (0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01);
    — GOST2001-CryptoPro-B с oid-ом 1.2.643.2.2.35.2 (0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x02);
    — GOST2001-CryptoPro-C с oid-ом 1.2.643.2.2.35.3 (0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03).
    Для ключей ГОСТ Р 34.10 с длиной 256 бит определены еще два oid-а для базовых точек:
    — GOST2001-CryptoPro-XchA с oid-ом 1.2.643.2.2.36.0 (0x2a, 0x85, 0x03, 0x02, 0x02, 0x24, 0x00);
    — GOST2001-CryptoPro-XchB с oid-ом 1.2.643.2.2.36.1 (0x2a, 0x85, 0x03, 0x02, 0x02, 0x24, 0x01).
    Однако в реальности эти oid-ы ссылаются на базовые точки GOST2001-CryptoPro-A с oid-ом 1.2.643.2.2.35.1 и GOST2001-CryptoPro-C с oid-ом 1.2.643.2.2.35.3 соответственно.
    И это следует учитывать при обработке базовых точек с этими oid-ами.

    Для генерации ключевой пары используется функция gcry_pk_genkey следующего вида:

    gcry_error_t gcry_pk_genkey (gcry sexp t *key_pair, gcry sexp t key_spec ).
    

    В переменной parms должны быть установлены параметры для генерации ключевой пары в формате внутреннего S-выражения (sexp). Для генерации ключевой пары по ГОСТ параметры задаются в виде следующего S-выражения:

    (genkey (есс (curve базовая_точка))), где 

    ecc определяет генерацию ключевой пары на эллиптических кривых, а базовая точка должна указывать конкретную точку, рекомендуемую ТК-26. Именно указанная базовая точка определяет, какая ключевая пара будет сгенерирована. Если указать, например, GOST2012-tc26-A или GOST2012-tc26-В, то будет сгенерирована ключевая пара по ГОСТ Р 34.10-2012 с длиной ключа 512 бит. Вместо nickname базовой точки можно указывать напрямую oid:

    (genkey (есс (curve «1.2.643.2.2.35.3»)))

    В последнем случае предполагается генерация ключевой пары по ГОСТ Р 34.10 с длиной ключа 256 бит и базовой точкой GOST2001-CryptoPro-C.

    Ниже приведен пример программы на языке C, который демонстрирует генерацию ключей

    GenKey.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include <gcrypt.h>
    /*Функция печати S-выражений*/
    static void
    show_sexp (const char *prefix, gcry_sexp_t a)
    {
      char *buf;
      size_t size;
      if (prefix)
        fputs (prefix, stderr);
      size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
      buf = gcry_xmalloc (size);
      gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
      fprintf (stderr, "%.*s", (int)size, buf);
      gcry_free (buf);
    }
    int main(int argc, char* argv[]) {
        gpg_error_t err;
        gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
    /*Базовые точки*/
        char *curve_gost[] = {"GOST2001-CryptoPro-A", "GOST2001-CryptoPro-B", "GOST2001-CryptoPro-C", "GOST2012-tc26-A", "GOST2012-tc26-B", NULL};
    /*Задаем параметры для генерации ключевой пары*/
        err = gcry_sexp_build (&key_spec, NULL,
                                   "(genkey (ecc (curve %s)))", curve_gost[1]);
        if (err) {
             fprintf(stderr, "creating S-expression failed: %s\n", gcry_strerror (err));
        	exit (1);
        }
        err = gcry_pk_genkey (&key_pair, key_spec);
        if (err){
            fprintf(stderr, "creating %s  key failed: %s\n", argv[1], gcry_strerror (err));
            exit(1);
        }
    /*Печать S-выражения ключевой пары*/
        show_sexp ("ECC GOST key pair:\n", key_pair);
    /*Сохраняем публичный ключ*/
        pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
        if (! pub_key) {
            fprintf(stderr, "public part missing in key\n");
            exit(1);
        }
    /*Печать S-выражения публичного ключа*/
        show_sexp ("ECC GOST public key:\n", pub_key);
    /*Сохраняем закрытый ключ*/
        sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
        if (! sec_key){
            fprintf(stderr, "private part missing in key\n");
            exit(1);
        }
    /*Печать S-выражения закрытого ключа*/
        show_sexp ("ECC GOST private key:\n", sec_key);
    /*Освобождаем память, занимаемую ключевой парой*/    
        gcry_sexp_release (key_pair);
    /*Освобождаем память, занимаемую параметрами ключевой пары*/    
        gcry_sexp_release (key_spec);
    }


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

    $cc –o GenKey GenKey.c –lgcrypt
    $

    После запуска модуля GenKey получим

    ключевую пару
    ECC GOST key pair:
    (key-data 
     (public-key 
      (ecc 
       (curve GOST2001-CryptoPro-B)
       (q #043484CF83F837AAC7ABD4707DE27F5A1F6161120C0D77B63DFFC7D50A7772A12D1E836E6257766E8B83209DD59845F8080BA29E9A86D0A6B6C2D68F44650B3A14#)
       )
      )
     (private-key 
      (ecc 
       (curve GOST2001-CryptoPro-B)
       (q #043484CF83F837AAC7ABD4707DE27F5A1F6161120C0D77B63DFFC7D50A7772A12D1E836E6257766E8B83209DD59845F8080BA29E9A86D0A6B6C2D68F44650B3A14#)
       (d #1ABB5A62BFF88C97567B467C6F4017242FE344B4F4BC8906CE40A0F9D51CBE48#)
       )
      )
     )
    ECC GOST public key:
    (public-key 
     (ecc 
      (curve GOST2001-CryptoPro-B)
      (q #043484CF83F837AAC7ABD4707DE27F5A1F6161120C0D77B63DFFC7D50A7772A12D1E836E6257766E8B83209DD59845F8080BA29E9A86D0A6B6C2D68F44650B3A14#)
      )
     )
    ECC GOST private key:
    (private-key 
     (ecc 
      (curve GOST2001-CryptoPro-B)
      (q #043484CF83F837AAC7ABD4707DE27F5A1F6161120C0D77B63DFFC7D50A7772A12D1E836E6257766E8B83209DD59845F8080BA29E9A86D0A6B6C2D68F44650B3A14#)
      (d #1ABB5A62BFF88C97567B467C6F4017242FE344B4F4BC8906CE40A0F9D51CBE48#)
      )
     )

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

    Хэширование документа


    Создание электронной подписи (ЭП) документа начинается с получения значения хэша от подписываемого документа. Для подписи документа может быть выбран один из алгоритмов:
    — 1.2.643.2.2.3 (0x2a, 0x85, 0x03, 0x02, 0x02, 0x03) — алгоритм подписи ГОСТ Р 34.10-2001 с ключом 256 с хэшированием по ГОСТ Р 34.11-94 с длиной хэша 256 бит;
    — 1.2.643.7.1.1.3.2 (0x2a, 0x85, 0x03, 0x07, 0x01, 0x01, 0x03, 0x02) — алгоритм подписи ГОСТ Р 34.10-2012 с ключом 256 с хэшированием по ГОСТ Р 34.11-2012 с длиной хэша 256 бит;
    — 1.2.643.7.1.1.3.3 (0x2a, 0x85, 0x03, 0x07, 0x01, 0x01, 0x03, 0x03) — алгоритм подписи ГОСТ Р 34.10-2012 с ключом 512 с хэшированием по ГОСТ Р 34.11-2012 с длиной хэша 512 бит.
    Эти алгоритмы определяют не только тип закрытого ключа, который будет использован для получения ЭП, но и алгоритм хэш-функции. В библиотеке GCrypt реализованы все три типа функций. Алгоритм хэширования ГОСТ Р 34.11-94 (с oid-ом параметра 1.2.643.2.2.30.1 — 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01) реализован под nickname-ом GOSTR3411_CP, алгоритм ГОСТ Р 34.11-2012 с длиной 256 бит (oid 1.2.43.7.1.1.2.2 — 0x2a, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x02) реализован под nickname-ом STRIBOG256 и алгоритм ГОСТ Р 34.11-2012 с длиной 512 бит (oid 1.2.43.7.1.1.2.3 — 0x2a, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x03) реализован под nickname-ом STRIBOG512.

    Ниже приведен код модуля на языке C для вычисления значения хэш от документа, хранящегося в файле

    digest_gcrypt.c :
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include <gcrypt.h>
    int main(int argc, char* argv[]) {
        gpg_error_t err;
        int algo = GCRY_MD_NONE;
        int i;
        unsigned char *h;
        size_t size;
        gcry_md_hd_t hd;
        FILE *fp;
        unsigned char buf[1024];	
        char *dgst_gost[] = {"GOSTR3411_CP", "STRIBOG256", "STRIBOG512", NULL};
        i = 0;
    /*Проверка параметров хэш-функции*/
        if (argc == 3)
            algo = gcry_md_map_name (argv[1]);
        if (algo == GCRY_MD_NONE) {
        	fprintf(stderr, "Usage: digest_gcrypt <nick_name_digest> <file_for_digest>\n");
            fprintf(stderr, "<nick_name_digest>=");
        	while (dgst_gost[i] != NULL){
                if (i > 0 ) 
                    fprintf(stderr, " | ", dgst_gost[i]);              
        	    fprintf(stderr, "%s", dgst_gost[i]);
        	    i++;
        	}
            fprintf(stderr, "\n");
        	exit (1);
        }
    /*Создаем контекст хэш функции*/
        err = gcry_md_open(&hd, algo, 0);
        if (err) { 
    fprintf (stderr, "LibGCrypt error %s\n",
           gcry_strerror (err));
            exit (1);
        }
    /*Открываем подписываемый файл*/
        if (!strcmp (argv[2], "-"))
            fp = stdin;
        else
            fp = fopen (argv[2], "r");
    
        if (fp == NULL) {
              fprintf(stderr, "Cannot fopen file=%s\n", argv[2]);
              exit(1);
        }
    /*Считаем хэш содержимого файла*/
        while (!feof (fp)) {
              size = fread (buf, 1, sizeof(buf), fp);
              gcry_md_write (hd, buf, size);
        }
    /*Сохраняем значение хэш*/
        h  = gcry_md_read(hd, 0);
    /*Печатаем значение хэш*/
        printf("Длина хеш %s = %d (в байтах)\n", argv[1], gcry_md_get_algo_dlen (algo));
        printf("Хэш от файла  %s:\n", argv[2]);
        for (i = 0; i < gcry_md_get_algo_dlen (algo); i++)
            printf("%02x", h[i]);
        printf("\n");
        fflush(stdout);
    /*Закрываем контекст*/
        gcry_md_reset(hd);
        gcry_md_close(hd);
    }

    Транслируем этот модуль и получаем утилиту вычисления хэш:

    $cc -o digest_file digest_file.c  -lgcrypt
    $./digest_file 
    Usage: digest_gcrypt <nick_name_digest> <file_for_digest>
    <nick_name_digest>=GOSTR3411_CP | STRIBOG256 | STRIBOG512
    $./digest_file  STRIBOG256 digest_file.c 
    Длина хеш STRIBOG256 = 32 (в байтах)
    Хэш от файла  digest_file.c:
    f6818dfb26073747266dc721c332d703eb21f2b17e3433c809e0e23b68443d4a
    $

    Формирование электронной подписи и ее проверка


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

    gcry_error_t gcry_pk_sign (gcry sexp t *r_sig, gcry sexp t data, gcry sexp t skey ), где

    r_sig -sexp-переменная, в которой будет сохранена электронная подпись,
    skey – sexp-переменная с закрытым ключом (см. выше), который используется для формирования подписи,
    data – sexp-переменная, в которой указываются тип подписи (в нашем случае gost) и хэш подписываемого документа.
    Здесь следует помнить, что значение хэш, поступающее на вход gcry_pk_sign для формирования подписи ГОСТ Р 34.10, должно быть в формате big-endian, т.е. фактически перевернуто (как сказал один товарищ: «Российская традиция рассматривать байты дайджеста в порядке little-endian»). С учетом этого замечания подготовка sexp-переменной data выглядит следующим образом:

    ...
    gcry_sexp_t data;
    unsigned char c;
    int len_xy;
    gcry_mpi_t x;
    …
    /*Проверяем архитектуру и инвертируем хэш*/
        printf("%s\n", *((unsigned char *) &arch) == 0 ? "Архитектура big-endian" : "Архитекткра little-endian");
        len_xy =  *((unsigned char *) &arch) == 0 ? 0:gcry_md_get_algo_dlen (algo);   
     for (i = 0; i < (len_xy/2); i++) {
                	    c = *(h + i);
                	    *(h + i) = *(h + len_xy - i - 1);
                	    *(h + len_xy - i - 1) = c;
        }
    fprintf(stderr, "Хэш длина=%d\n", gcry_md_get_algo_dlen (algo));
        for (i = 0; i < gcry_md_get_algo_dlen (algo); i++)
            printf("%02X", h[i]);
        fflush(stdout);
    /*Сохраняем хэш в mpi-переменной*/
        x = gcry_mpi_set_opaque_copy(NULL, h, gcry_md_get_algo_dlen (algo) * 8);
    /*Инициализируем sexp-переменную data исходными данными – тип и хэш*/
        err = gcry_sexp_build (&data, NULL, "(data (flags gost) (value %m))", x);
    /* Печатаем содержимое переменной data */
        show_sexp ("data :\n", data);
    Все готово для получения подписи и ее просмотра<source: lang=«cpp»>…
    gcry_sexp_t sig_r, sig_s;

    /*Подписываем хэш*/
    err = gcry_pk_sign (&sig, data, sec_key);
    if (err) {
    fprintf(stderr, «signing failed: %s\n», gcry_strerror (err));
    exit(1);
    }
    /* Печатаем подпись */
    show_sexp («ECC GOST SIG:\n», sig);
    /*Выбираем и печаем составные части подписи r и s*/
    sig_r = gcry_sexp_find_token (sig, «r», 0);
    if (!sig_r) {
    fprintf(stderr, «r part missing in sig\n»);
    exit(1);
    }
    show_sexp («ECC GOST Sig R-part:\n», sig_r);
    sig_s = gcry_sexp_find_token (sig, «s», 0);
    if (! sig_s) {
    fprintf(stderr, «s part missing in sig\n»);
    exit(1);
    }
    show_sexp («ECC GOST Sig S-part:\n», sig_s);
    …Проверить подпись можно следующим образом:
    …
        err = gcry_pk_verify (sig, data, pub_key);
        if (err) {
              putchar ('\n');
              show_sexp ("seckey:\n", sec_key);
              show_sexp ("data:\n", data);
              show_sexp ("sig:\n", sig);
              fprintf(stderr, "verify failed: %s\n", gcry_strerror (err));
              exit(1);
        }
    …
    

    Проверка электронной подписи ГОСТ Р 34.10 в сертификатах


    imageОдними из главных объектов инфраструктуры открытых ключей (ИОК) являются сертификаты X509. Рекомендации ТК-26 по составу и структуре сертификатов изложены в документе «ТЕХНИЧЕСКАЯ СПЕЦИФИКАЦИЯ ИСПОЛЬЗОВАНИЯ АЛГОРИТМОВ ГОСТ Р 34.10, ГОСТ Р 34.11 В ПРОФИЛЕ СЕРТИФИКАТА И СПИСКЕ ОТЗЫВА СЕРТИФИКАТОВ (CRL) ИНФРАСТРУКТУРЫ ОТКРЫТЫХ КЛЮЧЕЙ X.509 (Утверждена решением заседания технического комитета по стандартизации «Криптографическая защита информации» (Протокол N13 от 24.04.2014 г.) ». Именно в соответствии с этими рекомендациями выпускают сертификаты все аккредитованные в Минкомсвязи России УЦ.

    Для проверки подписи в сертификате необходимо (см. выше) получить хэш проверяемого сертификата, его подпись и открытый ключ корневого сертификата. Сразу отметим, что для самоподписанного сертификата все эти данные хранятся в одном сертификате.
    Для работы с объектами ИОК/PKI (сертификаты, CMS, запросы
    и т.п.), как правило, используется библиотека KSBA, которая на данный момент не поддерживает рекомендации ТК-26, хотя опыт такой поддержки есть. В принципе, ничто не мешает добавить поддержку рекомендаций ТК-26 в проект ksba.
    На данном этапе, этапе тестирования GCrypt, для работы с объектами ИОК/PKI (сертификаты и т.п.) с россицйской криптографией удобно использовать скриптовые языки типа Python, Tcl и т.д. Был выбран скриптовый язык Tcl . На нем легко и просто написать прототип программы, который затем перенести на язык C. В составе Tcl имеется пакет PKI, который содержит процедуры разбора (parse) объектов ИОК, в частности, процедура разбора сертификатов ::pki::x509::parse_cert. На базе процедуры parse_cert была разработана процедура parse_gost_cert, которая находится в файле

    parse_cert_gost_oid.tcl
    proc parse_cert_gost {cert} {
    #    parray ::pki::oids
    #puts "parse_cert_gost=$cert"
        set cert_seq ""
        if { [string range $cert 0 9 ] == "-----BEGIN" } {
    	array set parsed_cert [::pki::_parse_pem $cert "-----BEGIN CERTIFICATE-----" "-----END CERTIFICATE-----"]
    	set cert_seq $parsed_cert(data)
        } else {
    #FORMAT DER
    	set cert_seq $cert
        }
        set finger [::sha1::sha1 $cert_seq]
        set ret(fingerprint) $finger
    
        binary scan  $cert_seq H* certdb 
        set ret(certdb) $certdb
    #puts "CERTDB=$certdb"
    	array set ret [list]
    
    	# Decode X.509 certificate, which is an ASN.1 sequence
    	::asn::asnGetSequence cert_seq wholething
    	::asn::asnGetSequence wholething cert
    	set ret(cert) $cert
    
    	set ret(cert) [::asn::asnSequence $ret(cert)]
    if {0} {
        set ff [open "/tmp/tbs.der" w]
        fconfigure $ff -translation binary
        puts -nonewline $ff $ret(cert)
        close $ff
    }
    	binary scan $ret(cert) H* ret(cert)
    
    	::asn::asnPeekByte cert peek_tag
    	if {$peek_tag != 0x02} {
    		# Version number is optional, if missing assumed to be value of 0
    		::asn::asnGetContext cert - asn_version
    		::asn::asnGetInteger asn_version ret(version)
    		incr ret(version)
    	} else {
    		set ret(version) 1
    	}
    
    	::asn::asnGetBigInteger cert ret(serial_number)
    	::asn::asnGetSequence cert data_signature_algo_seq
    		::asn::asnGetObjectIdentifier data_signature_algo_seq ret(data_signature_algo)
    	::asn::asnGetSequence cert issuer
    	::asn::asnGetSequence cert validity
    		::asn::asnGetUTCTime validity ret(notBefore)
    		::asn::asnGetUTCTime validity ret(notAfter)
    	::asn::asnGetSequence cert subject
    	::asn::asnGetSequence cert pubkeyinfo
    
    	binary scan  $pubkeyinfo H* pubkeyinfoG
    	set ret(pubkeyinfo) $pubkeyinfoG
    
    
    		::asn::asnGetSequence pubkeyinfo pubkey_algoid
    
    	binary scan  $pubkey_algoid H* pubkey_algoidG
    	set ret(pubkey_algoid) $pubkey_algoidG
    
    			::asn::asnGetObjectIdentifier pubkey_algoid ret(pubkey_algo)
    		::asn::asnGetBitString pubkeyinfo pubkey
    
    	set extensions_list [list]
    	while {$cert != ""} {
    		::asn::asnPeekByte cert peek_tag
    
    		switch -- [format {0x%02x} $peek_tag] {
    			"0xa1" {
    				::asn::asnGetContext cert - issuerUniqID
    			}
    			"0xa2" {
    				::asn::asnGetContext cert - subjectUniqID
    			}
    			"0xa3" {
    				::asn::asnGetContext cert - extensions_ctx
    				::asn::asnGetSequence extensions_ctx extensions
    				while {$extensions != ""} {
    					::asn::asnGetSequence extensions extension
    						::asn::asnGetObjectIdentifier extension ext_oid
    
    						::asn::asnPeekByte extension peek_tag
    						if {$peek_tag == 0x1} {
    							::asn::asnGetBoolean extension ext_critical
    						} else {
    							set ext_critical false
    						}
    
    						::asn::asnGetOctetString extension ext_value_seq
    
    					set ext_oid [::pki::_oid_number_to_name $ext_oid]
    
    					set ext_value [list $ext_critical]
    
    					switch -- $ext_oid {
    						id-ce-basicConstraints {
    							::asn::asnGetSequence ext_value_seq ext_value_bin
    
    							if {$ext_value_bin != ""} {
    								::asn::asnGetBoolean ext_value_bin allowCA
    							} else {
    								set allowCA "false"
    							}
    
    							if {$ext_value_bin != ""} {
    								::asn::asnGetInteger ext_value_bin caDepth
    							} else {
    								set caDepth -1
    							}
    						
    							lappend ext_value $allowCA $caDepth
    						}
    						default {
    							binary scan $ext_value_seq H* ext_value_seq_hex
    							lappend ext_value $ext_value_seq_hex
    						}
    					}
    
    					lappend extensions_list $ext_oid $ext_value
    				}
    			}
    		}
    	}
    	set ret(extensions) $extensions_list
    
    	::asn::asnGetSequence wholething signature_algo_seq
    	::asn::asnGetObjectIdentifier signature_algo_seq ret(signature_algo)
    	::asn::asnGetBitString wholething ret(signature)
    
    	# Convert values from ASN.1 decoder to usable values if needed
    	set ret(notBefore) [::pki::x509::_utctime_to_native $ret(notBefore)]
    	set ret(notAfter) [::pki::x509::_utctime_to_native $ret(notAfter)]
    	set ret(serial_number) [::math::bignum::tostr $ret(serial_number)]
    	set ret(data_signature_algo) [::pki::_oid_number_to_name $ret(data_signature_algo)]
    	set ret(signature_algo) [::pki::_oid_number_to_name $ret(signature_algo)]
    	set ret(pubkey_algo) [::pki::_oid_number_to_name $ret(pubkey_algo)]
    	set ret(issuer) [::pki::x509::_dn_to_string $issuer]
    	set ret(subject) [::pki::x509::_dn_to_string $subject]
    	set ret(signature) [binary format B* $ret(signature)]
    	binary scan $ret(signature) H* ret(signature)
    
    	# Handle RSA public keys by extracting N and E
    #puts "PUBKEY_ALGO=$ret(pubkey_algo)"
    	switch -- $ret(pubkey_algo) {
    		"rsaEncryption" {
    			set pubkey [binary format B* $pubkey]
    			binary scan $pubkey H* ret(pubkey)
    
    			::asn::asnGetSequence pubkey pubkey_parts
    			::asn::asnGetBigInteger pubkey_parts ret(n)
    			::asn::asnGetBigInteger pubkey_parts ret(e)
    
    			set ret(n) [::math::bignum::tostr $ret(n)]
    			set ret(e) [::math::bignum::tostr $ret(e)]
    			set ret(l) [expr {int([::pki::_bits $ret(n)] / 8.0000 + 0.5) * 8}]
    			set ret(type) rsa
    		} 
    		"GostR2012_256" -
    		"GostR2012_512" -
    		"GostR2001" -
    		"1.2.643.2.2.19" -
    		"1.2.643.7.1.1.1.1" -
    		"1.2.643.7.1.1.1.2" {
    #	gost2001, gost2012-256,gost2012-512
    			set pubkey [binary format B* $pubkey]
    #puts "LL=[string length $pubkey]"
    if {[string length $pubkey] < 100} {
        set pubk [string range $pubkey 2 end]
    } else {
        set pubk [string range $pubkey 3 end]
    }
    set pubkey_revert [string reverse $pubk]
    binary scan $pubkey_revert H* ret(pubkey_rev)
    			binary scan $pubkey H* ret(pubkey)
    			set ret(type) gost
    			::asn::asnGetSequence pubkey_algoid pubalgost
    #OID - параметра
    			::asn::asnGetObjectIdentifier pubalgost ret(paramkey)
    	set ret(paramkey) [::pki::_oid_number_to_name $ret(paramkey)]
    #OID - Функция хэша
    			::asn::asnGetObjectIdentifier pubalgost ret(hashkey)
    	set ret(hashkey) [::pki::_oid_number_to_name $ret(hashkey)]
    #puts "ret(paramkey)=$ret(paramkey)\n"
    #puts "ret(hashkey)=$ret(hashkey)\n"
    		}
    	}
    	return [array get ret]
    }
    
    proc set_nick_for_oid {} {
    #    set ::pki::oids(1.2.643.2.2.19) "gost2001pubKey"
    #    set ::pki::oids(1.2.643.2.2.3)  "gost2001withGOST3411_94"
        set ::pki::oids(1.2.643.100.1)  "OGRN"
        set ::pki::oids(1.2.643.100.5)  "OGRNIP"
        set ::pki::oids(1.2.643.3.131.1.1) "INN"
        set ::pki::oids(1.2.643.100.3) "SNILS"
    #Алгоритмы подписи
        set ::pki::oids(1.2.643.2.2.3) "ГОСТ Р 34.10-2001-256"
        set ::pki::oids(1.2.643.7.1.1.3.2) "ГОСТ Р 34.10-2012-256"
        set ::pki::oids(1.2.643.7.1.1.3.3) "ГОСТ Р 34.10-2012-512"
    #    set ::pki::oids(1.2.643.2.2.3) "gost"
    #    set ::pki::oids(1.2.643.7.1.1.3.2) "gost"
    #    set ::pki::oids(1.2.643.7.1.1.3.3) "gost"
    #Алгоритмы ключа
    #    set ::pki::oids(1.2.643.2.2.19) "ГОСТ Р 34.10-2001"
    #    set ::pki::oids(1.2.643.7.1.1.1.1) "ГОСТ Р 34.10-2012 256 байт"
    #    set ::pki::oids(1.2.643.7.1.1.1.2) "ГОСТ Р 34.10-2012 512 байт"
        set ::pki::oids(1.2.643.2.2.19) "GostR2001"
        set ::pki::oids(1.2.643.7.1.1.1.1) "GostR2012_256"
        set ::pki::oids(1.2.643.7.1.1.1.2) "GostR2012_512"
    #Oid-ы параметров ключа ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-2012-256
        set ::pki::oids(1.2.643.2.2.35.0) "GOST2001-test"
        set ::pki::oids(1.2.643.2.2.35.1) "GOST2001-CryptoPro-A"
        set ::pki::oids(1.2.643.2.2.35.2) "GOST2001-CryptoPro-B"
        set ::pki::oids(1.2.643.2.2.35.3) "GOST2001-CryptoPro-C"
    #    { "GOST2001-CryptoPro-A",     set ::pki::oids("GOST2001-CryptoPro-XchA" },
    #    { "GOST2001-CryptoPro-C",     set ::pki::oids("GOST2001-CryptoPro-XchB" },
        set ::pki::oids(1.2.643.2.2.36.0) "GOST2001-CryptoPro-A"
        set ::pki::oids(1.2.643.2.2.36.1) "GOST2001-CryptoPro-C"
    #Oid-ы параметров ключа ГОСТ Р 34.10-2012-512
        set ::pki::oids(1.2.643.7.1.2.1.2.1) "GOST2012-tc26-A"
        set ::pki::oids(1.2.643.7.1.2.1.2.2) "GOST2012-tc26-B"
    #Nick для хэш
        set ::pki::oids(1.2.643.7.1.1.2.2) "STRIBOG256"
        set ::pki::oids(1.2.643.7.1.1.2.3) "STRIBOG512"
        set ::pki::oids(1.2.643.2.2.30.1) "GOSTR3411_CP"
    }


    Процедура parse_gost_cert предназначена для разбора сертификатов на базе российской криптографии.
    В этом файле находится также процедура присвоения nickname-мов oid-ам российской криптографии с учетом проекта GCrypt:
    proc set_nick_for_oid {} {
        set ::pki::oids(1.2.643.100.1)  "OGRN"
        set ::pki::oids(1.2.643.100.5)  "OGRNIP"
        set ::pki::oids(1.2.643.3.131.1.1) "INN"
        set ::pki::oids(1.2.643.100.3) "SNILS"
    #Алгоритмы подписи
        set ::pki::oids(1.2.643.2.2.3) "ГОСТ Р 34.10-2001-256"
        set ::pki::oids(1.2.643.7.1.1.3.2) "ГОСТ Р 34.10-2012-256"
        set ::pki::oids(1.2.643.7.1.1.3.3) "ГОСТ Р 34.10-2012-512"
    #Алгоритмы ключа
        set ::pki::oids(1.2.643.2.2.19) "GostR2001"
        set ::pki::oids(1.2.643.7.1.1.1.1) "GostR2012_256"
        set ::pki::oids(1.2.643.7.1.1.1.2) "GostR2012_512"
    #Oid-ы параметров ключа ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-2012-256
        set ::pki::oids(1.2.643.2.2.35.0) "GOST2001-test"
        set ::pki::oids(1.2.643.2.2.35.1) "GOST2001-CryptoPro-A"
        set ::pki::oids(1.2.643.2.2.35.2) "GOST2001-CryptoPro-B"
        set ::pki::oids(1.2.643.2.2.35.3) "GOST2001-CryptoPro-C"
        set ::pki::oids(1.2.643.2.2.36.0) "GOST2001-CryptoPro-A"
        set ::pki::oids(1.2.643.2.2.36.1) "GOST2001-CryptoPro-C"
    #Oid-ы параметров ключа ГОСТ Р 34.10-2012-512
        set ::pki::oids(1.2.643.7.1.2.1.2.1) "GOST2012-tc26-A"
        set ::pki::oids(1.2.643.7.1.2.1.2.2) "GOST2012-tc26-B"
    #Nick для хэш
        set ::pki::oids(1.2.643.7.1.1.2.2) "STRIBOG256"
        set ::pki::oids(1.2.643.7.1.1.2.3) "STRIBOG512"
        set ::pki::oids(1.2.643.2.2.30.1) "GOSTR3411_CP"
    }

    Процедура parse_gost_cert позволяет получить TBS-сертификат, подпись сертификата, тип подписи, открытый ключ. Если мы рассматриваем самоподписанный сертификат, то этого достаточно для проверки подписи. Если же мы проверяем подпись сертификата, подписанного (выпущенного) другим сертификатом (issuer и subject сертификата не совпадают), то процедура получения информации для проверки подписи выглядит следующим образом:

    — из проверяемого сертификата извлекаем его TBS-сертификат, тип подписи и саму подпись;
    — из корневого сертификата извлекаем открытый ключ.

    Самое ответственное при подготовке исходных данных для проверки подписи сертификата, это строгое следование рекомендациям TK-26. Для значения открытого ключа они звучат так:
    Представление открытого ключа GostR3410-2012-256-PublicKey идентично представлению открытого ключа ГОСТ Р 34.10-2001 [IETF RFC 4491], и ДОЛЖНО содержать 64 октета, где первые 32 октета содержат координату x в представлении little-endian, и вторые 32 октета содержат координату y в представлении little-endian.

    Представление открытого ключа GostR3410-2012-512-PublicKey ДОЛЖНО содержать
    128 октетов, где первые 64 октета содержат координату x в представлении little-endian, и вторые 64 октета содержат координату у в представлении little-endian.
    При выгрузке подписи следует руководствоваться следующим:
    Алгоритм подписи ГОСТ Р 34.10-2012 с длиной хэш-кода 256 бит используется для формирования цифровой подписи в форме двух 256-битных чисел, r и s. Её представление в виде строки октетов (OCTET STRING) идентично представлению подписи ГОСТ Р 34.10-2001 [IETF RFC 4491] и состоит из 64 октетов; при этом первые 32 октета содержат число s в представлении big-endian (старший октет записывается первым), а вторые 32 октета содержат число r в представлении big-endian.

    Алгоритм подписи ГОСТ Р 34.10-2012 с длиной хэш-кода 512 используется для формирования цифровой подписи в форме двух 512-битных чисел, открытые ключи согласно r и s. Её представление в виде строки октетов (OCTET STRING) состоит из 128 октетов; при этом первые 64 октета содержат число s в представлении big-endian (старший октет записывается первым), а вторые 64 октета содержат число r в представлении big-endian.
    С учетом этих рекомендаций Tcl-модуль parse_certs_for_verify_load.tcl подготовки исходных данных для проверки подписи сертификата

    выглядит следующим образом:
    
    #!/usr/bin/tclsh
    #загружаем пакет PKI
    package require pki
    #загружаем файл с процедурой разбора ГОСТ-ых сертификатов
    source parse_cert_gost_oid.tcl
    if {$argc != 2} {
        puts "Usage: parse_certs_for_verify_load.tcl <проверяемый сертификат> <корневой сертификат>"
        exit 1
    }
    #Проверяемый сертификат
    if {[file exists "[lindex $argv 0]"] == 0 } {
        puts "Usage: parse_certs_for_verify_load.tcl <проверяемый сертификат> <корневой сертификат>"
        puts "Отсутствует файл [lindex $argv 0]"
        exit 1
    }
    #Корневой сертификат
    if {[file exists "[lindex $argv 1]"] == 0 } {
        puts "Usage: parse_certs_for_verify_load.tcl <проверяемый сертификат> <корневой сертификат>"
        puts "Отсутствует файл [lindex $argv 1]"
        exit 1
    }
    #Устанавливаем nick-и для ГОСТ-овых oid-ов
    set_nick_for_oid
    
    set file [lindex $argv 0]
    set f [open $file r]
    set cert [read $f]
    close $f
    #READ DER-format
    if { [string range $cert 0 9 ] != "-----BEGIN" } {
    	set fd [open $file]
    	chan configure $fd -translation binary
    	set cert [read $fd]
    	close $fd
    }
    
    array set cert_user [parse_cert_gost $cert]
    #Читай рекомендации ТК-26
    set len_sign [expr [string length $cert_user(signature)] /2]
    set sign_r [string range $cert_user(signature) $len_sign end]
    set sign_s [string range $cert_user(signature) 0 [expr $len_sign - 1]]
    
    #puts "Корневой сертификат: $file"
    set file [lindex $argv 1]
    set f [open $file r]
    set cert [read $f]
    close $f
    #READ DER
        if { [string range $cert 0 9 ] != "-----BEGIN" } {
    	set fd [open $file]
    	chan configure $fd -translation binary
    	set cert [read $fd]
    	close $fd
        }
    
    #Распарсиваем в массив корневой сертификат
    array set cert_ca [parse_cert_gost $cert]
    #Читай рекомендации ТК-26
    set len_key [expr [string length $cert_ca(pubkey_rev)]/2]
    set key_pub_left [string range $cert_ca(pubkey_rev) $len_key end]
    set key_pub_right [string range $cert_ca(pubkey_rev) 0 [expr $len_key - 1]]
    puts "/*Делаем C-код: Исходные данные для проверки подписи сертификата*/"
    #TBS-проверяемого сертификата
    puts "char tbc\[\] = \"[string toupper $cert_user(cert)]\";"
    #Тип хэш-функции
    puts "char hash_type\[\] = \"$cert_ca(hashkey)\";"
    #Открытый ключ корневого сертификата
    puts "unsigned char pub_key_ca\[\] = \"(public-key \""
    puts "\"(ecc \""
    puts "\" (curve $cert_ca(paramkey))\""
    puts "\" (q #04[string toupper $key_pub_left$key_pub_right]#)\""
    puts "\")\""
    puts "\")\";"
    #Подпись проверяемого сертификата
    puts "unsigned char sig_cert\[\] = \"(sig-val\"" 
    puts "\"($cert_ca(type) \""
    puts "\" (r #[string toupper $sign_r]#)\""
    puts "\" (s #[string toupper $sign_s]#)\""
    puts "\")\""
    puts "\")\";"
    puts "/*Сохраните вывод в файле TEST_from_TCL.h*/"
    puts "/*Оттранслируйте модуль TEST_from_Tcl.c: cc -o TEST_from_Tcl TEST_from_Tcl.c -lgcrypt и выполните модуль TEST_from_Tcl*/"
    


    Для тестирования возьмем два реальных сертификата:

    сертификат \"УЦ 1 ИС ГУЦ.pem\"
    -----BEGIN CERTIFICATE-----
    MIIGrDCCBlugAwIBAgILAOvBBVQAAAAAAFkwCAYGKoUDAgIDMIIBSjEeMBwGCSqG
    SIb3DQEJARYPZGl0QG1pbnN2eWF6LnJ1MQswCQYDVQQGEwJSVTEcMBoGA1UECAwT
    Nzcg0LMuINCc0L7RgdC60LLQsDEVMBMGA1UEBwwM0JzQvtGB0LrQstCwMT8wPQYD
    VQQJDDYxMjUzNzUg0LMuINCc0L7RgdC60LLQsCwg0YPQuy4g0KLQstC10YDRgdC6
    0LDRjywg0LQuIDcxLDAqBgNVBAoMI9Cc0LjQvdC60L7QvNGB0LLRj9C30Ywg0KDQ
    vtGB0YHQuNC4MRgwFgYFKoUDZAESDTEwNDc3MDIwMjY3MDExGjAYBggqhQMDgQMB
    ARIMMDA3NzEwNDc0Mzc1MUEwPwYDVQQDDDjQk9C+0LvQvtCy0L3QvtC5INGD0LTQ
    vtGB0YLQvtCy0LXRgNGP0Y7RidC40Lkg0YbQtdC90YLRgDAeFw0xNjAzMTYxMjAy
    NTFaFw0yNzA3MTIxMjAyNTFaMIIBITEaMBgGCCqFAwOBAwEBEgwwMDc3MTA0NzQz
    NzUxGDAWBgUqhQNkARINMTA0NzcwMjAyNjcwMTEeMBwGCSqGSIb3DQEJARYPZGl0
    QG1pbnN2eWF6LnJ1MTwwOgYDVQQJDDMxMjUzNzUg0LMuINCc0L7RgdC60LLQsCDR
    g9C7LiDQotCy0LXRgNGB0LrQsNGPINC0LjcxLDAqBgNVBAoMI9Cc0LjQvdC60L7Q
    vNGB0LLRj9C30Ywg0KDQvtGB0YHQuNC4MRUwEwYDVQQHDAzQnNC+0YHQutCy0LAx
    HDAaBgNVBAgMEzc3INCzLiDQnNC+0YHQutCy0LAxCzAJBgNVBAYTAlJVMRswGQYD
    VQQDDBLQo9CmIDEg0JjQoSDQk9Cj0KYwYzAcBgYqhQMCAhMwEgYHKoUDAgIjAQYH
    KoUDAgIeAQNDAARAx70Y7WYQ4ODtdiSSx3MJnr1GQBEIExiPO/LWj1TRKES1OcDI
    YgtdOBGVYSvbsStl10jkAOG0OpnGsd2by4m+LaOCA0MwggM/MA8GA1UdEwEB/wQF
    MAMBAf8wHQYDVR0OBBYEFBGIaV7vyOlz23pXNbzSAfMF/qfRMAsGA1UdDwQEAwIB
    hjCCAYsGA1UdIwSCAYIwggF+gBSLmDuJGFHo75wCeLjqyNQgslXJXaGCAVKkggFO
    MIIBSjEeMBwGCSqGSIb3DQEJARYPZGl0QG1pbnN2eWF6LnJ1MQswCQYDVQQGEwJS
    VTEcMBoGA1UECAwTNzcg0LMuINCc0L7RgdC60LLQsDEVMBMGA1UEBwwM0JzQvtGB
    0LrQstCwMT8wPQYDVQQJDDYxMjUzNzUg0LMuINCc0L7RgdC60LLQsCwg0YPQuy4g
    0KLQstC10YDRgdC60LDRjywg0LQuIDcxLDAqBgNVBAoMI9Cc0LjQvdC60L7QvNGB
    0LLRj9C30Ywg0KDQvtGB0YHQuNC4MRgwFgYFKoUDZAESDTEwNDc3MDIwMjY3MDEx
    GjAYBggqhQMDgQMBARIMMDA3NzEwNDc0Mzc1MUEwPwYDVQQDDDjQk9C+0LvQvtCy
    0L3QvtC5INGD0LTQvtGB0YLQvtCy0LXRgNGP0Y7RidC40Lkg0YbQtdC90YLRgIIQ
    NGgeQMtB7zOpoLfIdpKaKTBZBgNVHR8EUjBQMCagJKAihiBodHRwOi8vcm9zdGVs
    ZWNvbS5ydS9jZHAvZ3VjLmNybDAmoCSgIoYgaHR0cDovL3JlZXN0ci1wa2kucnUv
    Y2RwL2d1Yy5jcmwwJgYFKoUDZG8EHQwb0JrRgNC40L/RgtC+LdCf0YDQviBDU1Ag
    My42MCUGA1UdIAQeMBwwCAYGKoUDZHEBMAgGBiqFA2RxAjAGBgRVHSAAMIHGBgUq
    hQNkcASBvDCBuQwj0J/QkNCa0JwgwqvQmtGA0LjQv9GC0L7Qn9GA0L4gSFNNwrsM
    INCf0JDQmiDCq9CT0L7Qu9C+0LLQvdC+0Lkg0KPQpsK7DDbQl9Cw0LrQu9GO0YfQ
    tdC90LjQtSDihJYgMTQ5LzMvMi8yLTk5OSDQvtGCIDA1LjA3LjIwMTIMONCX0LDQ
    utC70Y7Rh9C10L3QuNC1IOKEliAxNDkvNy8xLzQvMi02MDMg0L7RgiAwNi4wNy4y
    MDEyMAgGBiqFAwICAwNBAKVYokUvb7XAMPJF38ZPKO2BFBldmGEfqsfmsiO35Y52
    kTkx512H3YLqWMrOLjIfVMJhc+DTCNeXWY6bhK4/DRU=
    -----END CERTIFICATE-----

    и его корневой сертификат \"ГУЦ Минкомсвязь.pem\":
    -----BEGIN CERTIFICATE-----
    MIIFGTCCBMigAwIBAgIQNGgeQMtB7zOpoLfIdpKaKTAIBgYqhQMCAgMwggFKMR4w
    HAYJKoZIhvcNAQkBFg9kaXRAbWluc3Z5YXoucnUxCzAJBgNVBAYTAlJVMRwwGgYD
    VQQIDBM3NyDQsy4g0JzQvtGB0LrQstCwMRUwEwYDVQQHDAzQnNC+0YHQutCy0LAx
    PzA9BgNVBAkMNjEyNTM3NSDQsy4g0JzQvtGB0LrQstCwLCDRg9C7LiDQotCy0LXR
    gNGB0LrQsNGPLCDQtC4gNzEsMCoGA1UECgwj0JzQuNC90LrQvtC80YHQstGP0LfR
    jCDQoNC+0YHRgdC40LgxGDAWBgUqhQNkARINMTA0NzcwMjAyNjcwMTEaMBgGCCqF
    AwOBAwEBEgwwMDc3MTA0NzQzNzUxQTA/BgNVBAMMONCT0L7Qu9C+0LLQvdC+0Lkg
    0YPQtNC+0YHRgtC+0LLQtdGA0Y/RjtGJ0LjQuSDRhtC10L3RgtGAMB4XDTEyMDcy
    MDEyMzExNFoXDTI3MDcxNzEyMzExNFowggFKMR4wHAYJKoZIhvcNAQkBFg9kaXRA
    bWluc3Z5YXoucnUxCzAJBgNVBAYTAlJVMRwwGgYDVQQIDBM3NyDQsy4g0JzQvtGB
    0LrQstCwMRUwEwYDVQQHDAzQnNC+0YHQutCy0LAxPzA9BgNVBAkMNjEyNTM3NSDQ
    sy4g0JzQvtGB0LrQstCwLCDRg9C7LiDQotCy0LXRgNGB0LrQsNGPLCDQtC4gNzEs
    MCoGA1UECgwj0JzQuNC90LrQvtC80YHQstGP0LfRjCDQoNC+0YHRgdC40LgxGDAW
    BgUqhQNkARINMTA0NzcwMjAyNjcwMTEaMBgGCCqFAwOBAwEBEgwwMDc3MTA0NzQz
    NzUxQTA/BgNVBAMMONCT0L7Qu9C+0LLQvdC+0Lkg0YPQtNC+0YHRgtC+0LLQtdGA
    0Y/RjtGJ0LjQuSDRhtC10L3RgtGAMGMwHAYGKoUDAgITMBIGByqFAwICIwEGByqF
    AwICHgEDQwAEQI+lv3kQI8jWka1kMVdbvpvFioP0Pyn3Knmp+2XD6KgPWnXEIlSR
    X8g/IYracDr51YsNc2KE3C7mkH6hA3M3ofujggGCMIIBfjCBxgYFKoUDZHAEgbww
    gbkMI9Cf0JDQmtCcIMKr0JrRgNC40L/RgtC+0J/RgNC+IEhTTcK7DCDQn9CQ0Jog
    wqvQk9C+0LvQvtCy0L3QvtC5INCj0KbCuww20JfQsNC60LvRjtGH0LXQvdC40LUg
    4oSWIDE0OS8zLzIvMi05OTkg0L7RgiAwNS4wNy4yMDEyDDjQl9Cw0LrQu9GO0YfQ
    tdC90LjQtSDihJYgMTQ5LzcvMS80LzItNjAzINC+0YIgMDYuMDcuMjAxMjAuBgUq
    hQNkbwQlDCPQn9CQ0JrQnCDCq9Ca0YDQuNC/0YLQvtCf0YDQviBIU03CuzBDBgNV
    HSAEPDA6MAgGBiqFA2RxATAIBgYqhQNkcQIwCAYGKoUDZHEDMAgGBiqFA2RxBDAI
    BgYqhQNkcQUwBgYEVR0gADAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
    /zAdBgNVHQ4EFgQUi5g7iRhR6O+cAni46sjUILJVyV0wCAYGKoUDAgIDA0EA23Re
    ec/Y27rpMi+iFbgWCazGY3skBTq5ZGsQKOUxCe4mO7UBDACiWqdA0nvqiQMXeHgq
    o//fO9pxuIHtymwyMg==
    -----END CERTIFICATE-----

    Подготовим исходные данные для проверки сертификата «УЦ 1 ИС ГУЦ.pem»:

    $ ./parse_certs_for_verify_load.tcl  "УЦ 1 ИС ГУЦ.pem" "ГУЦ Минкомсвязь.pem" > TEST_from_TCL.h
    $echo "Содержимое файла TEST_from_TCL.h"
    $cat TEST_from_TCL.h
    /*Делаем C-код: Исходные данные для проверки подписи сертификата*/
    char tbc[] = "3082065B . . . ";
    char hash_type[] = "GOSTR3411_CP";
    unsigned char pub_key_ca[] = "(public-key "
    "(ecc "
    " (curve GOST2001-CryptoPro-A)"
    " (q #040FA8E8C365FBA9792AF7293FF4838AC59BBE5B573164AD91D6C8231079BFA58FFBA1377303A17E90E62EDC8462730D8BD5F93A70DA8A213FC85F915422C4755A#)"
    ")"
    ")";
    unsigned char sig_cert[] = "(sig-val"
    "(gost "
    " (r #913931E75D87DD82EA58CACE2E321F54C26173E0D308D797598E9B84AE3F0D15#)"
    " (s #A558A2452F6FB5C030F245DFC64F28ED8114195D98611FAAC7E6B223B7E58E76#)"
    ")"
    ")";
    /*Сохраните вывод в файле TEST_from_TCL.h*/
    /*Оттранслируйте модуль TEST_from_Tcl.c: cc -o TEST_from_Tcl TEST_from_Tcl.c -lgcrypt и выполните модуль TEST_from_Tcl*/
    $

    Проверка подписи сертификата выполняется модулем:

    TEST_from_TCL.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdarg.h>
    #include <gcrypt.h>
    
    #include "TEST_from_TCL.h"
    
    #define digitp(p)     (*(p) >= '0' && *(p) <= '9')
    #define hexdigitp(a)  (digitp (a)                     \
                           || (*(a) >= 'A' && *(a) <= 'F')  \
                           || (*(a) >= 'a' && *(a) <= 'f'))
    #define xtoi_1(p)     (*(p) <= '9'? (*(p)- '0'): \
                           *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
    #define xtoi_2(p)     ((xtoi_1(p) * 16) + xtoi_1((p)+1))
    #define xmalloc(a)    gcry_xmalloc ((a))
    
    static void
    show_sexp (const char *prefix, gcry_sexp_t a)
    {
      char *buf;
      size_t size;
    
      if (prefix)
        fputs (prefix, stderr);
      size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
      buf = gcry_xmalloc (size);
    
      gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
      fprintf (stderr, "%.*s", (int)size, buf);
      gcry_free (buf);
    }
    /* Convert STRING consisting of hex characters into its binary
       representation and return it as an allocated buffer. The valid
       length of the buffer is returned at R_LENGTH.  The string is
       delimited by end of string.  The function returns NULL on
       error.  */
    static void *
    hex2buffer (const char *string, size_t *r_length)
    {
      const char *s;
      unsigned char *buffer;
      size_t length;
    
      buffer = xmalloc (strlen(string)/2+1);
      length = 0;
      for (s=string; *s; s +=2 )
        {
          if (!hexdigitp (s) || !hexdigitp (s+1))
            return NULL;           /* Invalid hex digits. */
          ((unsigned char*)buffer)[length++] = xtoi_2 (s);
        }
      *r_length = length;
      return buffer;
    }
    
    int main(int argc, char* argv[]) {
        gpg_error_t err;
        int algo;
        gcry_md_hd_t hd;
        unsigned char *tbs_ptr;
        size_t len_tbs;
        int i;
        unsigned char *h;
        gcry_sexp_t pub_key;
        gcry_sexp_t data;
        gcry_sexp_t sig;
        gcry_mpi_t x;
        int len_xy;
        unsigned char c;
    /*Для тестирования архитектуры little-endian или big-endian*/
        unsigned short arch = 1; /* 0x0001 */
    
        tbs_ptr = hex2buffer(tbc, &len_tbs);
        if (tbs_ptr == NULL) {
          fprintf (stderr, "Bad tbs\n");
    	exit(1);
        }
        algo = gcry_md_map_name (hash_type);
        if (algo == GCRY_MD_NONE)
        {
          fprintf (stderr, "Unknown algorithm '%s'\n", hash_type);
          exit (1);
        }
    
        err = gcry_md_open(&hd, algo, 0);
        if (err)
        {
          fprintf (stderr, "LibGCrypt error %s/%s\n",
              gcry_strsource (err),
              gcry_strerror (err));
            exit (1);
        }
        gcry_md_write (hd, tbs_ptr, len_tbs);
        h  = gcry_md_read(hd, 0);
    //    len_xy = gcry_md_get_algo_dlen (algo);
    /*Проверяем архитектуру и инвертируем хэш*/
        printf("%s\n", *((unsigned char *) &arch) == 0 ? "Архитектура big-endian" : "Архитекткра little-endian");
        len_xy =  *((unsigned char *) &arch) == 0 ? 0:gcry_md_get_algo_dlen (algo);
        for (i = 0; i < (len_xy/2); i++) {
                	    c = *(h + i);
                	    *(h + i) = *(h + len_xy - i - 1);
                	    *(h + len_xy - i - 1) = c;
        }
    
    fprintf(stderr, "Хэш длина=%d\n", gcry_md_get_algo_dlen (algo));
        for (i = 0; i < gcry_md_get_algo_dlen (algo); i++)
            printf("%02X", h[i]);
    //    printf("\n  %s\n", tbc);
        fflush(stdout);
    /*Сохраняем хэш */
        x = gcry_mpi_set_opaque_copy(NULL, h, gcry_md_get_algo_dlen (algo) * 8);
    
    /*Закрываем контекст хэширования*/
        gcry_md_reset(hd);
        gcry_md_close(hd);
    /*Контекст хэша*/
        err = gcry_sexp_build (&data, NULL,
                                 "(data (flags gost) (value %m))", x);
        show_sexp ("ECC GOST data cert:\n", data);
    fprintf (stderr, "\nStep 1\n");
    /*Контекст публичного ключа корневого сертификата*/
        err = gcry_sexp_sscan (&pub_key, NULL, pub_key_ca,
                               strlen (pub_key_ca));
        if (err){
    	fprintf(stderr, "TEST_SEXP: er gcry_sexp_sscan for pub_key_ca\n");
    	exit(1);
        }
        show_sexp ("ECC GOST public key:\n", pub_key);
    fprintf (stderr, "Step 2\n");
    /*Контекст подписи проверяемого сертификата*/
        err = gcry_sexp_sscan (&sig, NULL, sig_cert, strlen (sig_cert));
        if (err){
    	fprintf(stderr, "TEST_SEXP: er gcry_sexp_sscan for sig_cert\n");
    	exit(1);
        }
        show_sexp ("ECC GOST sig cert:\n", sig);
    fprintf (stderr, "Step 3\n");
    /*Проверка подписи сертификата*/
        err = gcry_pk_verify (sig, data, pub_key);
        if (err) {
            fprintf (stderr, "TEST_SEXP: verify cert failed\n");
            exit (1);
        }
        fprintf (stderr, "TEST_SEXP: verify cert OK!!\n");
    }
    

    Транслируем и выполняем утилиту TEST_from_TCL:

    $cc –o TEST_from_TCL TEST_from_TCL.c –lgcrypt
    $./TEST_from_TCL
    Архитекткра little-endian 
    Хэш длина=32 
    D485903E7E8D60820118329060C558B9C733D53CA608C0C79363ECE7B4C1F799ECC GOST data cert: 
    (data  
    (flags gost) 
    (value #D485903E7E8D60820118329060C558B9C733D53CA608C0C79363ECE7B4C1F799#) 
    ) 
    Step 1 
    ECC GOST public key: 
    (public-key  
    (ecc  
     (curve GOST2001-CryptoPro-A) 
     (q #040FA8E8C365FBA9792AF7293FF4838AC59BBE5B573164AD91D6C8231079BFA58FFBA1377303A17E90E
    62EDC8462730D8BD5F93A70DA8A213FC85F915422C4755A#) 
     ) 
    ) 
    Step 2 
    ECC GOST sig cert: 
    (sig-val  
    (gost  
     (r #913931E75D87DD82EA58CACE2E321F54C26173E0D308D797598E9B84AE3F0D15#) 
     (s #A558A2452F6FB5C030F245DFC64F28ED8114195D98611FAAC7E6B223B7E58E76#) 
     ) 
    ) 
    Step 3 
    TEST_SEXP: verify cert OK!! 
    $

    Как видим, проверка подписи сертификата «УЦ 1 ИС ГУЦ.pem» прошла успешно. Осталось проверить сам корневой сертификат «ГУЦ Минкомсвязь.pem». Все просто, достаточно выполнить команду:

    $ parse_certs_for_verify_load.tcl  "ГУЦ Минкомсвязь.pem"  "ГУЦ Минкомсвязь.pem" > TEST_from_TCL.h
    $ и т.д.

    Если кто захочет проверить сертификаты с другими ГОСТ-овыми ключами (ГОСТ Р 34.10-2012-256 или ГОСТ Р 34.10-2012-512), то может воспользоваться УЦ CAFL63 и подготовить любые сертификаты:



    Итак, проделанные изыскания показали, что библиотека GCrypt вполне может использоваться для работы с российской криптографией. Ближайшая перспектива видится в доработке библиотеки KSBA и расширении пакета pki скриптового языка Tcl (а может и Python) поддержкой российской криптографии.

    Те, кто хочет использовать библиотеку GCrypt для шифрования, рекомендую заглянуть сюда.
    Поделиться публикацией
    Комментарии 47
      +3
      Но сегодня в стандартной версии openssl отсутствует поддержка как ГОСТ Р 34.11-2012, так и ГОСТ Р 34.10-2012. Более того в версии 1.1 поддержка криптографии ГОСТ исключена из стандартной поставки («The GOST engine was out of date and therefore it has been removed.»).

      Чем не устраивает вот эта, которую "убрали?" https://github.com/gost-engine/engine


      Пример билда: https://github.com/rnixik/docker-openssl-gost/blob/master/Dockerfile

        +2

        Помотрел, всем устраивает. Здорово, спасибо. Я думаю фраза > «The GOST engine was out of date and therefore it has been removed.» относится все же к ГОСТ Р 34.10-2001.
        Но одно другому не мешает. И будем верить, что ГОСТ-оый patch все же появится в OpenSSL. Выкрою время и прикручу этот патн к УЦ. Еще раз спасибою

          +1
          Да, здорово. Но я не нашел Магму, хотя ее алгоритмы легко реализуются через надстройку над ГОСТ28147-89. Кроме того, некоторые сопутствующие алгоритмы ТК 26 требуют
          внесения изменений не только в engine, но и в библиотеку OpenSSL. Ну и конечно поддержка TLS с новыми алгоритмами.
            0

            TLS — это, конечно, круто. В GCrypt TLS нет, это отдельная песня.

            0

            Еще раз спасибо. Собрал и подключил к УЦ CAFL63. Все работает. К сожалению, оттельные недоработки, как указал есть V2008, например, при просмотре сертификатов/запросов не отображаются отдельные поля, введенные ТК-26 (Issuer Sign Tool, Subject Sign Tool и т.п.):



            Но это дело наживное.

              0

              Закиньте пул-реквест на эти oid'ы, да будет всем щастье.

                0

                Сделаем. А вот как примерно должно выглядеть:


              0

              С победными реляциями я поторопился. К сожалению выпустить квалифицированный сертификат с этой версией openssl и gost-engine не удастся, не хватает обрабтки требуемых oid-ов:


              Error Loading extension section cert_ext
              140436202112768:error:22097081:X509 V3 routines:do_ext_nconf:unknown extension:crypto/x509v3/v3_conf.c:82:
              140436202112768:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:crypto/x509v3/v3_conf.c:47:name=issuerSignTool, value=@issuer_sign_tool_section

              Надо дорабатывать!

              0
              Подскажите в чем практический смысл данной библиотеки?

              Если требуется российская криптография, то нужны сертифицированные СКЗИ. Если нужно просто шифрование (любое), то пользуются AES и Co под который миллиард библиотек и примеров.
                0
                Если требуется российская криптография, то нужны сертифицированные СКЗИ.

                Это смотря где требуется. Кстати, при желании можно и GCrypt сертифицировать.


                очень много сервисов или приложений разработано на базе OpenSSL, который поддерживал работу с ГОСТ Р 34.10-2001.

                И это так. Берется openssl с поддержкой ГОСТ, берется PKCS#12 и вперед.
                Пример? Пожалуйста, "Работаем с реестром запрещенных ресурсов" .


                Да, и просто проверить, например, подпись.


                Ну, а потом, мы же патриоты, зачем нам AES, когда есть "Кузнечик".

                  0
                  Подскажите в чем практический смысл данной библиотеки?

                  Если требуется российская криптография, то нужны сертифицированные СКЗИ. Если нужно просто шифрование (любое), то пользуются AES и Co под который миллиард библиотек и примеров.

                  Рано или поздно контент обработанный ГОСТ'ом потребуется открыть на компьютере, владелец которого признает только СПО и не планирует устанавливать сртифицированную проприетарщину.
                    0

                    Да, именно об этом, в частности, и идет речь.

                  –1
                  Давайте не будем сами придумывать несуществующие «требования».

                  Если говорить о обязательном применении 2012-х ГОСТов, то это только в отношении КЭП, к которой данная статья не имеет отношения (см. 63-ФЗ в части обязанности применения сертифицированных средств ЭП).
                  Это же касается и утверждения, что «если требуется российская криптография, то нужны сертифицированные СКЗИ». Это не верное умозаключение.
                  Требования следуют из законов и подзаконных актов. Именно они определяют, в каких случаях должны применяться сертифицированные СКЗИ. Про ГОСТы в них абсолютно ничего не говорится. Другое дело, что сертификацию проходят только те СКЗИ (средства ЭП и т.д.), которые реализуют эти ГОСТы в соответствии с требованиями ФСБ к этим средствам.
                  По поводу бессмысленности получения сертификата на 2001-х ГОСТах (опять же с учетом «требований», которые соотносятся только с КЭП): научите, как сделать иначе до перехода ГУЦ на новый ПАК не нарушая сертификационных ограничений средств УЦ?
                    +1
                    научите, как сделать иначе до перехода ГУЦ на новый ПАК не нарушая сертификационных ограничений средств УЦ?

                    Сегодня уже много сертифицированных комплексов УЦ с ГОСТ Р 34.10-2012. Поэтому при получении сертификата надо спрашивать какой ключ будет у вашего сертификата (если ключевая пара для вас генерится на УЦ) и какой ключ у корневого сертификата УЦ. И там и там нужно, чтобы был ГОСТ Р 34.10-2012. Если ключевую пару генерируете сами, то используйте СКЗИ с поддержкой опять же ГОСТ Р 34.10-2012.


                    Если говорить о обязательном применении 2012-х ГОСТов, то это только в отношении КЭП

                    Но в статье и говорится о КЭП. Но требования про ГОСТ 2012 касается любой подписи по ГОСТ, а не только квалифицированной. Более того, юридически значимый документооборот может быть только с КЭП.


                    Конечно, если "не играть " с государством, то пару организаций могут организовать свой PKI, со своими правилами. Но это будет касаться только их и их, и за пределами этого круга эти сертификаты и подписи с использованием их никакого значения иметь не будут.

                      0
                      Сегодня уже много сертифицированных комплексов УЦ с ГОСТ Р 34.10-2012

                      Увы, этого не достаточно. Средства УЦ (в рамках условий их сертифицированного применения) не позволяют выпускать сертификаты со смешением алгоритмов подписи. Т.о. Для того, чтоб сертификат КЭП содержал ключ проверки с ГОСТ Р 34.10-2012, он должен быть подписан на этом же алгоритме квалифицированной подписью УЦ, который в свою очередь должен быть подписан ключом ГУЦ на том же ГОСТ Р 34.10-2012. А такового не существует (ссылка: e-trust.gosuslugi.ru/MainCA).
                      Но требования про ГОСТ 2012 касается любой подписи по ГОСТ, а не только квалифицированной.

                      Извольте пояснить понятие «подписи по ГОСТ» (на основании терминологии, принятой в нормативных документах, определяющих требования). Так же ссылку на данные требования в студию (имеются ввиду требования, обязательность которых проистекает из ФЗ, и имеющие статус нормативного акта).
                        0
                        Увы, этого не достаточно. Средства УЦ (в рамках условий их сертифицированного применения) не позволяют выпускать сертификаты со смешением алгоритмов подписи.

                        Это абсолютно не так. Ключ корневого сертификата — это его ключ, а ключ пользовательского сертификата — это его ключ. УЦ может иметь один тип ключ (например, ГОСТ Р 34.10-2012 длиной 256 бит), а подписывать сертификаты с другим типом ключа (например, ГОСТ Р 34.10-2012 длиной 256 бит). Попробуйте и поймете. Заявитель сам решает какой ключ у него будетИменно по этому в сертификате и присутствует поле — тип подписи сертификата. Все, что вы говорите относится только к самоподписанному сертификату.


                        Для того, чтоб сертификат КЭП содержал ключ проверки с ГОСТ Р 34.10-2012, он должен быть подписан на этом же алгоритме квалифицированной подписью УЦ, который в свою очередь должен быть подписан ключом ГУЦ на том же ГОСТ Р 34.10-2012.

                        А как может быть по другому (имея ввиду, что остается только ГОСТ Р 34.10-2012)? Именно так и есть. Но ключи по ГОСТ Р 34.10-2012 могут иметь разную длину.


                        Извольте пояснить понятие «подписи по ГОСТ»

                        Подпись по ГОСТ Р 34.10


                        Так же ссылку на данные требования в студию (имеются ввиду требования, обязательность которых проистекает из ФЗ, и имеющие статус нормативного акта).

                        Поясните

                          0
                          Попробуйте и поймете. Заявитель сам решает какой ключ у него будет

                          Попробовать я могу все, что угодно. В т.ч. я я экспериментировал с выпуском сертификата на ключ с ГОСТ Р 34.10-2012 (256 бит), подписанного на ГОСТ Р 34.10-2001. Работает. Однако в документации ПАК УЦ (в рамках его сертифицированного использования) такое смешение недопустимо. Именно поэтому, пока не будет сертификата ГУЦ на ГОСТ Р 34.10-2012 пользователи аккредитованных УЦ живут только на ГОСТ Р 34.10-2001. Про длину ключей в рамках ГОСТ Р 34.10-2012 я ничего не говорил.
                          Извольте пояснить понятие «подписи по ГОСТ»

                          Подпись по ГОСТ Р 34.10

                          Так, а теперь хотелось бы посмотреть на нормативный документ, ориентированный на пользователя (не выписка из закрытого документа, а ФЗ или подзаконный акт) где от него требуется именно «подпись по ГОСТ Р 34.10», а не «СКЗИ, имеющие подтверждение соответствия требованиям (сертификат соответствия)».
                          Если взглянут чуть внимательнее на ту бумажку (показанную нам ТК 26, которая вызывает бурление… разума, то там есть интересная фраза: "… в случаях, подлежащих регулированию со стороны ФСБ России". Напомню, что в разрезе 63-ФЗ (который регулирует аспекты ЭП) ФСБ определяет требования именно к КЭП и средствам работы с ней. Т.о. ни о каких требованиях, которые «касается любой подписи по ГОСТ» там не говорится. Отсюда и мой вопрос: может быть вы знаете что-то ешё?
                            0
                            я экспериментировал с выпуском сертификата на ключ с ГОСТ Р 34.10-2012 (256 бит), подписанного на ГОСТ Р 34.10-2001. Работает.

                            Здорово же


                            Однако в документации ПАК УЦ (в рамках его сертифицированного использования) такое смешение недопустимо.
                            Какого УЦ? А если недопустимо — плохое УЦ.

                            Именно поэтому, пока не будет сертификата ГУЦ на ГОСТ Р 34.10-2012 пользователи аккредитованных УЦ живут только на ГОСТ Р 34.10-2001.

                            Я не знаю про какой ГУЦ вы говорите, но он (тем более, если это государственный ГУЦ), должен срочно, срочно разворачивать новый УЦ. У нас и так проблем хватает у людей, чтобы их еще дважды заставлять платить за сертификаты, пусть и с КЭП.


                            Отсюда и мой вопрос: может быть вы знаете что-то ешё?

                            Ну если сформулируете почетче, то в меру своих сил ...

                              0
                              Я не знаю про какой ГУЦ вы говорите

                              Тот самый, сертификат которого стоит в корне цепочек доверия всех квалифицированных сертификатов. Пока ГУЦ не перейдет на новые ГОСТы таких сертификатов у пользователей не может быть в принципе. А они не шибко спешат, проблемы индейцев вождя не волнуют, а требований к ним (как и к гос.органам уметь принимать подпись на ГОСТ Р 34.10-2012) быть готовыми к какому-то сроку — нет. И это боль. Вероятное развитие событий будет таким: выпустят корень к концу года, и все УЦ в авральном режиме и за свой счет будут перевыпускать миллионы сертификатов, ибо вешать это на пользователей они не могут себе позволить.
                              Ну если сформулируете почетче, то в меру своих сил ...

                              Вроде и так предельно подробно расписал: известны ли вам документы, устанавливающие требования ко всем видам «ГОСТовой подписи», не только квалифицированной, перейти на ГОСТ Р 34.10-2012, ибо «выписка из документа ФСБ России от 31 января 2014 г. №149/7/1/3-58» не в счет?
                                0

                                Что сказать? Живем там где живем! Законы выполняются как выполняются, тут вы ох как правы:


                                проблемы индейцев вождя не волнуют

                                Про сертификат


                                Тот самый, сертификат которого стоит в корне цепочек доверия всех квалифицированных сертификатов. Пока ГУЦ не перейдет на новые ГОСТы таких сертификатов у пользователей не может быть в принципе. А они не шибко спешат

                                Да, именно так. И люди будут вынуждены платить дважды. Переход ГУЦ — провалил (А в чем была проблема — одному богу известна. Попросили бы меня, за день перевел бы и бесплатно, но бесплатно не интересно). Сейчас ходят слухи, что якобы будет перенос сроков, но это у нас в порядке вещей: правая рука не знает, что делает левая (илли знает?).


                                Вроде и так предельно подробно расписал: известны ли вам документы, устанавливающие требования ко всем видам «ГОСТовой подписи», не только квалифицированной, перейти на ГОСТ Р 34.10-2012, ибо «выписка из документа ФСБ России от 31 января 2014 г. №149/7/1/3-58» не в счет?

                                Помочь не могу, крогом слухи, хотя сам не терплю чтение на заборе. Из вините. Лучше про техники, науку, историю.

                                  0
                                  А в чем была проблема — одному богу известна.

                                  В чем проблема как раз известно: для перевода ГУЦ на новые рельсы им нужен новый ПАК, и не абы какой, а сертифицированный по КА. Такой надо сделать, потом сертифицировать, потом пройти все этапы ввода в эксплуатацию. А они пока на этапе «сертифицировать», если не ошибаюсь, и там песня долгая, с припевами и притопами.
                                    0
                                    В чем проблема как раз известно: для перевода ГУЦ на новые рельсы им нужен новый ПАК, и не абы какой, а сертифицированный по КА.

                                    Я уже писал и пример приводил и таких примеров мног.


                                    Такой надо сделать, потом сертифицировать, потом пройти все этапы ввода в эксплуатацию. А они пока на этапе «сертифицировать», если не ошибаюсь, и там песня долгая, с припевами и притопами.

                                    Да за это надо гнать в три шеи: люди-то при чем!!!!

                                    0
                                    крогом слухи

                                    Вот с этого я и начал.
                                    Давайте не будем сами придумывать несуществующие «требования»

                                    За что и минусанули, так мне и надо
                        +1
                        Давайте не будем сами придумывать несуществующие «требования».

                        Если вы имеете ввиду формулировку:


                        использование схемы подписи ГОСТ Р 34.10-2001 для формирования подписи после 31 декабря 2018 года не допускается!

                        то это официальная формулировка (требование) регулятора, т.е. ФСБ России, и она прописывается сегодня в каждом заключении на СКЗИ, которое сертифицируется по «Требованиям к средствам электронной подписи», утвержденным приказом ФСБ России № 796. Так что никто и ничего не придумывает. Мы их просто должны выполнять

                          0
                          В первую очередь мы должны выполнять требования ФЗ о использовании сертифицированных средств ЭП при создании и проверке КЭП. А статья, как я её прочел, и комментарии про Open Source. Т.ч. это две разные песни, пересекающиеся только в области понятия ГОСТ, что не есть требования, а лишь стандарт. В требования стандарт превращается только в нормативных актах при определенных условиях.
                            0
                            В первую очередь мы должны выполнять требования ФЗ о использовании сертифицированных средств ЭП при создании и проверке КЭП.

                            Кто-нибудь это оспаривает? Все УЦ должны создаваться набе сертифицированных средств! Но я как гражданин могу просматривать и сертификаты и электронные подписи чем мне удобно, посмотрите комментарий от ls1 :


                            Рано или поздно контент обработанный ГОСТ'ом потребуется открыть на компьютере, владелец которого признает только СПО и не планирует устанавливать сртифицированную проприетарщину.

                            Более того, и СПО от OpenSource может быть сертифицировано. Такие примеры в России есть и с криптографией тоже.


                            А требования никто не отменял, наоборот, речь идет о том как их выполнить. А уж потом будем думать о сертификации и т.д.

                              0
                              … я как гражданин могу просматривать и сертификаты и электронные подписи чем мне удобно

                              А смысл? Это не проверка а ознакомление с содержанием. Это разные, в смысле принятия решения на их основе, действия. Проверка подразумевает в качестве результата однозначный ответ: действительна подпись или нет. А для этого только так: ст.5 п.4 63-ФЗ
                              … для создания и проверки <квалифицированной> электронной подписи используются средства электронной подписи, имеющие подтверждение соответствия требованиям
                              ...


                              СПО от OpenSource может быть сертифицировано. Такие примеры в России есть и с криптографией тоже.

                              Примеры, пожалуйста, где формуляры (указанные в сертификате соответствия ФСБ) таких средств содержат исходники, из которых допускается тех.документацией собирать СКЗИ самостоятельно, а не готовые бинарники, в студию.
                                0

                                Вроде и сказать нечего, кроме одного: OpenSource один из двигателей прогресса, в том числе и в российском PKI.

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

                                    Не совсем понимаю притенцию

                                      0
                                      Статья и комментарии изобилуют утверждениями, что для электронной подписи (без уточнения, что только квалифицированной) с 2019 года должен применяться исключительно ГОСТ Р 34.10-2012.

                                      Это не так.

                                      Утверждается, что переход на ГОСТ Р 34.10-2012 при использовании несертифицированных СКЗИ (ибо статья не про них), позволит обеспечить юридическую значимость.

                                      Это не так.

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

                                      Это тоже не так. Даже если назвать ее «квалифицированной», что совсем не то же самое, что ГОСТовая, то это тоже не совсем так. Есть условия признания трех видов (определенных в ФЗ) ЭП равнозначными собственноручной подписи. В соответствии с этими условиями усиленная неквалифицированная может оказаться более значимой, чем КЭП (например, если она создана при помощи несертифицированного средства ЭП).

                                      Я, возможно, нудный, но такие вот неточности пускают многих по ложному пути, от которого боли больше, чем от родных регуляторов.
                                        0
                                        Статья и комментарии изобилуют утверждениями, что для электронной подписи (без уточнения, что только квалифицированной) с 2019 года должен применяться исключительно ГОСТ Р 34.10-2012.

                                        Да, сегодня пока так — это требование ФСБ


                                        Утверждается, что переход на ГОСТ Р 34.10-2012 при использовании несертифицированных СКЗИ (ибо статья не про них), позволит обеспечить юридическую значимость.

                                        Это не правда. Нигде такого утверждения нет и быть не могло. Оно бессмысленно, т.к. юридическая значимость понятие юридическое, а этим все сказано


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

                                        А можно пример, в каком госоргане у нас принимают электронную подпись не по ГОСТ, RSA? например


                                        Я, возможно, нудный, но такие вот неточности пускают многих по ложному пути, от которого боли больше, чем от родных регуляторов.

                                        И что это за ложный путь? В чем он заключается? Уж не в том ли, что при разработке СКЗИ с криптографией ГОСТ можно опираться на разработке OpenSource?!
                                        Про регуляторов скромно умолчу.

                                          0
                                          Да, сегодня пока так — это требование ФСБ

                                          Увы на свои неоднократные вопросы я так эти требования не увидел. В том документе, на который косвенно ссылались речь только о КЭП.
                                          Нигде такого утверждения нет и быть не могло. Оно бессмысленно, т.к. юридическая значимость понятие юридическое, а этим все сказано

                                          Извиняюсь, тут уже я не точно выразился, речь шла о том что есть «требования», а статья призвана их удовлетворить. Не удовлетворит, увы.
                                          А можно пример, в каком госоргане у нас принимают электронную подпись не по ГОСТ, RSA? например

                                          Легко:
                                          • ФНС принимает RSA подпись от физиков в ЛК
                                          • В технологии ЕГАИС принимаются технолонические неквалифицированные сертификаты
                                          • Гос.торговые площадки по 44-ФЗ работают с НЭП...

                                          И что это за ложный путь? В чем он заключается? Уж не в том ли, что при разработке СКЗИ с криптографией ГОСТ можно опираться на разработке OpenSource?!

                                          В том числе. Многие уверены, что если сертификаты у них на ГОСТе и тем паче выпущены аккредитованным УЦ, то для подписи они могут использовать что угодно/удобно/нравится.
                                          А потом суд о непризнании электронной подписи под договором на основании того, что она создана в нарушение 63-ФЗ (при помощи того же OpenSSL), аннулирование договора, замороженное бабло на счетах контрагента и боль…
                                            0
                                            В том числе. Многие уверены, что если сертификаты у них на ГОСТе и тем паче выпущены аккредитованным УЦ, то для подписи они могут использовать что угодно/удобно/нравится.
                                            А потом суд о непризнании электронной подписи под договором на основании того, что она создана в нарушение 63-ФЗ (при помощи того же OpenSSL), аннулирование договора, замороженное бабло на счетах контрагента и боль…

                                            Это вы о чем-то о своем, наболевшем. Если пользователь разбрасывается своим закрытым ключом, это его проблемы!!! Если он ему не доверяет, то будь добр отзови сертификат. И OpenSource здесь ни причем. Весь мир работает на нем, и с электронной подписью, прежде всего: был бы только > легитимин Сертификат


                                            А как он его хранит, чем подписывает и проверяет, это его дело. Если сертификат не отозван и недоказано, что ключ украли (но опять же отзови сертификат, все как с паспортом), то и подпись действительна. Все определяется сертификатом: он определяет легитимность подписи, все остальное отлукавого.

                                              0
                                              Это вы о чем-то о своем, наболевшем.

                                              Это не о своем, а о пользователях (владельцах бизнеса и руководителях, «ИБ-шниках», ИТ-шниках и т.д.), которые начитавшись экспертных статей, но не заглянув в первоисточники, руководствовались «чем подписывает и проверяет, это его дело».
                                              Я уже писал, но повторюсь еще раз по поводу:
                                              Но в статье и говорится о КЭП.

                                              КЭП регулируется 63-ФЗ, где в ст.5 сказано однозначно:
                                              … для создания и проверки электронной подписи используются средства электронной подписи, имеющие подтверждение соответствия требованиям, установленным в соответствии с настоящим Федеральным законом.

                                              Там же в статье 10 указаны требования к участникам электронного взаимодействия:
                                              использовать для создания и проверки квалифицированных электронных подписей, создания ключей квалифицированных электронных подписей и ключей их проверки средства электронной подписи, имеющие подтверждение соответствия требованиям, установленным в соответствии с настоящим Федеральным законом.

                                              И далее про условия признания:
                                              … проверка осуществляется с использованием средств электронной подписи, имеющих подтверждение соответствия требованиям, установленным в соответствии с настоящим Федеральным законом…

                                              Выше я писал не про «разбрасывается своим закрытым ключом», а именно от том, какие средства и как пользователь использует для подписания и проверки электронных документов квалифицированной электронной подписью. Да, тут как с примером про ПДД, кого не проверят (сейчас почти никого), того пронесло, но бывают и грустные исключения. Две недели назад ФНС заявила, что планирует заняться этим более плотно, для них это шикарный источник поступления дополнительных средств в бюджет: выявили использование несертифицированных средств подписи (например, пресловутых «облачных») — отказали в налоговом вычете, вкатили миллионные штрафы за не предоставление декларации, т.к. то, что пришло ранее по формальным признакам признается не подписанным надлежащим образом. Т.ч. в ближайшей перспективе это боль массовая.
                                              И OpenSource здесь ни причем. Весь мир работает на нем

                                              Увы (ну или к счастью), но мы живем в РФ и на нас распространяются её законы.
                                              Оставлю за скобками, что разработка криптографических средств, это лицензируемый (313 ПП) вид деятельности. Эта тема отдельного обсуждения.

                                              Надеюсь, что теперь я расставил все точки над «i».
                                                0
                                                Это не о своем, а о пользователях (владельцах бизнеса и руководителях, «ИБ-шниках», ИТ-шниках и т.д.), которые начитавшись экспертных статей, но не заглянув в первоисточники, руководствовались «чем подписывает и проверяет, это его дело».

                                                Давайте договоримся, что речь идет о государсивенной системе PKI/ИОК. Исходя из этого, гражданин может подписывать документы только имея на руках СЕРТИФИКАТ, полученный в УЦ, аккредитованном в государственной системе аккредитации. И имея на руках легитимный сертификат и иже с ним закрытый ключ, который он в своих же интересах (как паспорт и многое другое) должен хранить как сеница око, он может с помощью этой пары (сертификат + закрытый ключ) подписать что-либо. Проверить какие средства (да и зачем это проверять, проверяется подпись) для подписи он использовал НЕВОЗМОЖНО. Гражданин носит с собой ключ (тем более если это токен со встроенной криптографией) и компьютер такать ему с собой не надо. Нем более, если надо посмотреть кто подписал документ (аналог https). Утратил ключ — отвечай. Итак, подписать всегда можно только имея на руках легитимные ключ и сертификат. О чем спор?


                                                выявили использование несертифицированных средств подписи (например, пресловутых «облачных») — отказали в налоговом вычете,

                                                А что хранится в облаке? Уж не ключ ли? Так накажите УЦ, вфдавший сертификат!!!!


                                                Честно говоря, я не понимаю о чем вы? Толи о технической безграмотности, толи о правовой, толи о безалаберности? О чем?


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

                                                А здесь, что обсуждать надо? Как гражданин, а тем более свободный художник, разрабатывать я могу все, но продавать, сертифицировать, если нет лицензии соответствующей, нет.
                                                Точки говорите, пусть стоят, на то они и точки

                                                  0
                                                  речь идет о государсивенной системе PKI/ИОК

                                                  Извините, Владимир, я не нашел федерального закона о «Государственной системе PKI». Скиньте ссылку, изучу и буду готов дальше дискутировать в контексте этой системы.
                                                  СЕРТИФИКАТ, полученный в УЦ, аккредитованном в государственной системе аккредитации

                                                  Это, видимо, все-таки про квалифицированную ЭП из 63-ФЗ, цитаты из которого приводил выше. Заметьте, что не свое мнение, и не ссылки на гуру Хабра, а конкретные нормативные документы.
                                                  Проверить какие средства (да и зачем это проверять, проверяется подпись) для подписи он использовал НЕВОЗМОЖНО

                                                  Зачем — это если есть в этом заинтересованность, например, финансовая (примеры выше), т.е. если я заинтересован в том, чтобы признать, например, наше с вами соглашение, подписанное КЭП, недействительным и профит будет выше трудозатрат, я это сделаю.
                                                  Как — тоже не большая проблема. Например, загляну в поля сертификата, которые согласно 795 приказу ФСБ, должны содержать сведения о сертифицированном средстве ЭП. Допустим, вы подделали это поле в запросе и обманом заставили УЦ выпустить сертификат. Уверены на 100%, что завтра к вам не заглянут в гости маски-шоу с выемкой средств электронной подписи в рамках расследования мошенничества (например опять же по моему заказу)?
                                                  Кстати, проверка подписи включает в себя проверку сертификата, это по поводу «зачем это проверять, проверяется подпись».
                                                  тем более если это токен со встроенной криптографией

                                                  Ну это как бы не совсем не «что хочу» и не опенсорс, это вполне себе сертифицированное СКЗИ.
                                                  А что хранится в облаке? Уж не ключ ли? Так накажите УЦ, выдавший сертификат!!!!

                                                  В общем смысле сервис подписи (облако) и УЦ, это разные сущности, и вполне себе могут быть разными организациями.
                                                  Честно говоря, я не понимаю о чем вы? Толи о технической безграмотности, толи о правовой, толи о безалаберности? О чем?

                                                  Я о накоплении заблуждений, основанных на свободном пересказе других пересказов и т.д. в отрыве от первоисточников. Технические действия, как и любые другие, имеют свои правовые (юридические) последствия, и наоборот, правовые нормы тесно связаны с технической реализацией предъявляемых ими требований. Все очень тесно переплетено и взаимосвязано.
                                                  Как гражданин, а тем более свободный художник, разрабатывать я могу все

                                                  С этим не спорю, и деньги для себя тоже можно рисовать в чуланчике ради любви к искусству, и пистолеты точить в гараже на токарном станке… до поры до времени. Это я к тому, что согласно ПП 313 исключения из лицензирования относится только к тех.обслуживанию, но не к разработке. Вероятность, что вас за это пожурят, конечно, ниже чем в случае с деньгами/пистолетами.

                                                  Подытожу сказанное: нарушать, конечно можно (тащ майор, это гипотетически), но если правовые последствия от этого ниже, чем выгода.
                                                  Но вот если мы говорим о КЭП, то это (обычно) что-то более весомое, чем эксперименты, с вполне конкретными правовыми последствиями. Стоит ли заигрывать с государством?
                                                    0
                                                    Например, загляну в поля сертификата, которые согласно 795 приказу ФСБ, должны содержать сведения о сертифицированном средстве ЭП

                                                    Вы их там всегда найдете — сертификат выдан аккредитованным УЦ. А вот где и как я задействую сертификат, это тайна за семью замками и маски здесь не помогут.


                                                    Я вам трержу-твержу — твержу о проверке сертификаты, а вы опять


                                                    Кстати, проверка подписи включает в себя проверку сертификата, это по поводу «зачем это проверять, проверяется подпись».

                                                    Разве можно проверить по-другому???


                                                    Спасибо. Пора работать

                                                      0
                                                      А вот где и как я задействую сертификат, это тайна за семью замками

                                                      Вероятно, имелось ввиду «как я задействую закрытый ключ», т.к. сертификат применяется исключительно для проверки подписи.
                                                      Для начала ключ надо извлечь из контейнера сертифицированного СКЗИ (если это аппаратное СКЗИ с неизвлекаемым ключом, то задача еще более нетривиальная), в котором он создавался.
                                                      Маски обычно не ищут, а изымают. Потом работают эксперты, а они обычно находят. Можно, конечно, шифровать тома, прятать сервера и т.п. А оно вам надо?
                                                      Я вам трержу-твержу — твержу о проверке сертификаты, а вы опять

                                                      Создалось впечатление, что у вас есть возражение по приведенным мною аргументам, поэтому пытаюсь их разъяснить. Если нет, то предлагаю закруглить.
                                                        0
                                                        Вероятно, имелось ввиду «как я задействую закрытый ключ», т.к. сертификат применяется исключительно для проверки подписи.

                                                        Приехали. Сертификат прилагается в том или ином виде к подписанному документы (читаем rfc и ТК-26 по CMS-документам).


                                                        Для начала ключ надо извлечь из контейнера сертифицированного СКЗИ (если это аппаратное СКЗИ с неизвлекаемым ключом, то задача еще более нетривиальная), в котором он создавался.
                                                        Маски обычно не ищут, а изымают.

                                                        А это еще что за бандитизм? Токен PKCS#11 с неизвлекаемым ключом (какие маски в этом случае) лежит у меня в кармане!


                                                        по приведенным мною аргументам

                                                        Какие аргументы и про что? Не увидел предмета для возражений и, естественно, аргументов по этому предмету

                                          0
                                          Утверждается, что переход на ГОСТ Р 34.10-2012 при использовании несертифицированных СКЗИ (ибо статья не про них), позволит обеспечить юридическую значимость.

                                          Рекомендую прочитать этот материал.

                            +1
                            Давайте не будем сами придумывать несуществующие «требования».


                            По поводу «несуществующих требований», очень полезный материал размещен на habr:
                            Не ждем, а готовимся к переходу на новые стандарты криптографической защиты информации
                              0
                              У меня тоже есть несколько ответов от ГУЦ, не более грамотных, к сожалению. Опускание ключевых моментов. в письмах регуляторов плодит многостороннее их толкование
                              Я не говорю что требования не существуют, хочу лишь отметить, что стоит читать их правильно, не додумывая:
                              • ГОСТ — это не требование
                              • В контексте КЭП (а не вообще для эфемерного понятия «российской подписи») требуется использовать сертифицированные СКЗИ (средства ЭП и УЦ) в рамках тех.документации
                              • Однобокое исполнение требований не решение конкретной задачи, а эксперимент. Это как в ПДД: если я соблюдаю скоростной режим, но при этом в стельку и без прав, то это не означает, что я молодец.
                              • Гораздо продуктивнее общение экспертов складывается, если они в своих утверждениях опираются на первоисточники (прочитанные не по диагонали), а не на мнения других экспертов, иначе накопление ошибок и домыслов с накоплением итераций превращает предмет обсуждения в байку «о которой все что-то знают»
                                0
                                Это как в ПДД: если я соблюдаю скоростной режим, но при этом в стельку и без прав, то это не означает, что я молодец.

                                Аллегория красивая, то для КЭП не совсем подходит. В вашей ситуации вы можете добраться до цели и лечь в теплую постель — поста ГИБДД не пути не было и вас никто не остановил. Но если вы пойдете на ГОСУСЛУГИ с правильно заполненными полями сертификата, но выпущенным в неаккедитованном УЦ, то вы всегда будете остановлены.


                                У меня тоже есть несколько ответов от ГУЦ, не более грамотных, к сожалению. Опускание ключевых моментов. в письмах регуляторов плодит многостороннее их толкование

                                Тут я с вами полностью согласен и с этим (квалификацией) что-то надо делать.

                                  0
                                  Но если вы пойдете на ГОСУСЛУГИ с правильно заполненными полями сертификата, но выпущенным в неаккедитованном УЦ, то вы всегда будете остановлены.

                                  Так я вроде и не утверждал, что с НЭПом туда пускают.
                            0
                            Очень интересно
                              0
                              Так я вроде и не утверждал, что с НЭПом туда пускают.

                              но


                              но при этом в стельку и без прав

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

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