LibGCrypt или Клеопатра на службе российской криптографии

Более двух лет прошло после выхода первого релиза библиотеки libgcrypt с поддержкой базовой российской криптографией, а именно ГОСТ 28147-89, ГОСТ Р 34.11-94, ГОСТ Р 34.11-2012 (в реализации данной библиотеки STRIBOG256 и STRIBOG512), ГОСТ Р 34.10-2001 и ГОСТ Р 34.1-2012.

Однако практического применения, в отличие от openssl с поддержкой российской криптографии, данная библиотека пока не находит. С чем это связано и куда двигаться?

Преимущество openssl – это наличие утилиты командной строки openssl и поддержка в рамках одного проекта, подчеркиваю, в рамках одного проекта стандарта X509, помимо ядра криптографии протоколов PKCS7, CMS, TLS, PKCS7 и других. Тоже самое можно сказать о библиотеке NSS (Nework Security System) и ее использовании в решениях Mozilla.

К сожалению, в самом проекте libgcrypt этого нету. Здесь на помощь приходят другие проекты прикладного уровня, которые используют эту библиотеку. Прежде всего, это проект GNU Privacy Guard (GnuPG, GPG), в рамках которого предоставляются инструментальные средства шифрования и цифровой подписи, соответствующих стандарту OpenPGP. В рамках этого проекта нас будет интересовать инструментальное средство gpgsm, которое используется для предоставления сервиса цифрового шифрования и электронной подписи (ЭП) на базе сертификатов X.509 и протокола CMS/PKCS7. GpgSM используется в основном в качестве движка при обработке электронной почты S/MIME, в частности, в почтовом клиенте KMail. Но если мы говорим о сертификатах, то нельзя не упомянуть о графической утилите управления сертификатами X509 Kleopatra.

Так что же изменилось с выходом библиотеки libgcrypt-1.6.5 с точки зрения использования PKI (Public Key Infrastruture) с российской криптографией в повседневной жизни?

Решить начали с просмотра подписанного почтового сообщения. С почтового клиента Thunderbird поддержкой российской криптографии было отправлено подписанное сообщение:

image

К сожалению, почтовый клиент KMail, получив это сообщение, не смог проверить ЭП:

image

К сожалению, Клеопатра также отказывалась признавать российские сертификаты. И так, мы приступили к анализу ситуации. Естественно начали с библиотеки libgcrypt. Все тесты для российской криптографии в рамках проекта проходили успешно. Но анализ исходного кода показал, что в проекте для ГОСТ-криптографии используются только тестовые узлы замен для ГОСТ-28147-89 и ГОСТ Р 34.11-94, а также тестовые параметры алгоритма подписи ГОСТ Р 34.10-2001 и тестовые параметры алгоритма подписи ГОСТ Р 34.10-2012 с ключом 512. И первым делом пришлось добавить рабочие узлы замен и рабочие параметры алгоритмов подписи:

/* This static table defines all available curves,  ecc-curvec.c */
static const ecc_domain_parms_t domain_parms[] =
  {
    {
      /* (-x^2 + y^2 = 1 + dx^2y^2) */
      "Ed25519", 256, 0,
      MPI_EC_TWISTEDEDWARDS, ECC_DIALECT_ED25519,
      "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
      "-0x01",
      "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A",
      "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
      "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A",
      "0x6666666666666666666666666666666666666666666666666666666666666658"
    },
. . . 
    {
      "GOST2001-test", 256, 0,
      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
      "0x8000000000000000000000000000000000000000000000000000000000000431", // p
      "0x0000000000000000000000000000000000000000000000000000000000000007", // a
      "0x5fbff498aa938ce739b8e022fbafef40563f6e6a3472fc2a514c0ce9dae23b7e", // b
      "0x8000000000000000000000000000000150fe8a1892976154c59cfc193accf5b3", // n(q)

      "0x0000000000000000000000000000000000000000000000000000000000000002", // g_x
      "0x08e2a8a0e65147d4bd6316030e16d19c85c97f0a9ca267122b96abbcea7e8fc8", // g_y
    },
/*ORLOV*/
    {
      "GOST2001-A", 256, 0,
      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd97", // p
      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd94", // a
      "0x00000000000000000000000000000000000000000000000000000000000000a6", // b
      "0xffffffffffffffffffffffffffffffff6c611070995ad10045841b09b761b893", // n(q)
      "0x0000000000000000000000000000000000000000000000000000000000000001", // g_x
      "0x8d91e471e0989cda27df505a453f2b7635294f2ddf23e3b122acc99c9e9f1e14", // g_y
    },
. . .
    {
      "GOST2012-test", 511, 0,
      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
      "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d"
      "f1d852741af4704a0458047e80e4546d35b8336fac224dd81664bbf528be6373",	// p
      "0x0000000000000000000000000000000000000000000000000000000000000000"
	  "0000000000000000000000000000000000000000000000000000000000000007",	// a
      "0x1cff0806a31116da29d8cfa54e57eb748bc5f377e49400fdd788b649eca1ac4"
      "361834013b2ad7322480a89ca58e0cf74bc9e540c2add6897fad0a3084f302adc",	// b
      "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d"
      "a82f2d7ecb1dbac719905c5eecc423f1d86e25edbe23c595d644aaf187e6e6df",	// n(q)
      "0x24d19cc64572ee30f396bf6ebbfd7a6c5213b3b3d7057cc825f91093a68cd762"
      "fd60611262cd838dc6b60aa7eee804e28bc849977fac33b4b530f1b120248a9a",	// g_x
      "0x2bb312a43bd2ce6e0d020613c857acddcfbf061e91e5f2c3f32447c259f39b2"
      "c83ab156d77f1496bf7eb3351e1ee4e43dc1a18b91b24640b6dbb92cb1add371e",	// q_y
    },
/*ORLOV*/
{
      "GOST2012-512-A", 512, 0,
      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
      "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
	  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7",	// p
      "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
	  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC4",	// a
      "0xE8C2505DEDFC86DDC1BD0B2B6667F1DA34B82574761CB0E879BD081CFD0B6265"
	  "EE3CB090F30D27614CB4574010DA90DD862EF9D4EBEE4761503190785A71C760",	// b
      "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
	  "27E69532F48D89116FF22B8D4E0560609B4B38ABFAD2B85DCACDB1411F10B275",	// n(q)
      "0x0000000000000000000000000000000000000000000000000000000000000000"
	  "0000000000000000000000000000000000000000000000000000000000000003",	// g_x
      "0x7503CFE87A836AE3A61B8816E25450E6CE5E1C93ACF1ABC1778064FDCBEFA921"
	  "DF1626BE4FD036E93D75E6A50E3A41E98028FE5FC235F5B889A589CB5215F2A4",	// q_y
    },
. . .
    { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL }
  };

Также пришлось, естественно пришлось включать привязку параметров алгоритмов к их oid-ам (Идентификаторы объектов (OID) технического комитета по стандартизации «Криптографическая защита информации» (ТК 26):

/* This tables defines aliases for curve names, ecc-curves.c */
static const struct
{
  const char *name;  /* Our name.  */
  const char *other; /* Other name. */
} curve_aliases[] =
  {
  /*{ "Curve25519", "1.3.6.1.4.1.3029.1.5.1" },*/
    { "Ed25519",    "1.3.6.1.4.1.11591.15.1" },
. . .
/*ORLOV*/
    { "GOST2001-test", "1.2.643.2.2.35.0" },
    { "GOST2001-A", "1.2.643.2.2.35.1" },
    { "GOST2001-B", "1.2.643.2.2.35.2" },
    { "GOST2001-C", "1.2.643.2.2.35.3" },
    { "GOST2001-XA", "1.2.643.2.2.36.0"},
    { "GOST2001-XB", "1.2.643.2.2.36.1"},
    { "GOST2012-test", "1.2.643.7.1.2.1.2.0" },
    { "GOST2012-512-A", "1.2.643.7.1.2.1.2.1" },
    { "GOST2012-512-B", "1.2.643.7.1.2.1.2.2" },
    { NULL, NULL}
  };

Это был тот минимум с чего надо было начинать. Для всех алгоритмов, прежде всего ГОСТ Р 34.10 были прогнаны тестовые при меры (утилита benchmark, доработанная с учетом включения новых параметров. Полученные результаты были проверены на тестовых примерах ТК-26 с использованием ранее апробированных средств криптографической защиты информации LCC-2016 и ПБЗИ «СКЗИ ЛИРССЛ»:

/*Результаты, полученные  в libgcrypt */
GOST=gost512-B  512 bit, testno=8         30ms     900msseckey:
(private-key 
 (ecc 
  (curve GOST2012-512-B)
  (q #040A4293FF45328CBC6BA41A5F94C612C901FE97A7730E884CC81A701B8D27257DE70B21766BF79E5FAA1E9AE43543C6CF901D910DB5081BBB741F9DD3D9079A5725FDBD2F7A267F88626B5ED0D3EC687389AE01B63207C0C7FD3C86554DB77F21A16FB23327FEE72401087AF1128E662769B6A8F6CE2E27BF8713297CBB41B5A4#)
  (d #24ADC433139D97A3E8D5066EFCFD34A9705D4BC932A6FA1B52085B620416AE3772C5C7932C8B4E2666E6D6412F5BA1961F62575CA6058531EB3DA6044DB92D15#)
  )
 )
data:
(data 
 (flags gost)
 (value #3F05FAFCA2744B46839001314876C4169956F1F3A9A2BFA27A1F55C9EFA74D33CAF6F04EC5AF7591DC16D1BD1B2689C704DD2F2BBE67A7E54987EE08ABC1C213#)
 )
sig:
(sig-val 
 (gost 
  (r #7977D87E4060D9AF828B146A2A0EF3DFCDC1E35AF32EBAEF5C9364E46C9DB5C2A0159D8DB0E2DAE5C25B17A45454EC73394249DA8FE97951C7F391BB01B5EA5D#)
  (s #2EAFC644023E36CADCD0A86D3B9C2EB028AECBA46C89EE27A5081E090A3EAC496091E3A79FBE952019E0EB0925C94A6B6200256F96A1A38AB5E27E066541AC75#)
  )
 )

/* Результаты тестирования тестовых результатов в LCC-2016 */ 
Testing id-tc26-gost-3410-2012-512-paramSetB (1.2.643.7.1.2.1.2.2)
Find parameter set by OID OK
Digest:
3F05FAFCA2744B46839001314876C4169956F1F3A9A2BFA27A1F55C9EFA74D33CAF6F04EC5AF7591DC16D1BD1B2689C704DD
2F2BBE67A7E54987EE08ABC1C213
Private key:
24ADC433139D97A3E8D5066EFCFD34A9705D4BC932A6FA1B52085B620416AE3772C5C7932C8B4E2666E6D6412F5BA1961F62
575CA6058531EB3DA6044DB92D15
Private key loaded OK
Public key generated OK
Public key:
x: a4293ff45328cbc6ba41a5f94c612c901fe97a7730e884cc81a701b8d27257de70b21766bf79e5faa1e9ae43543c6cf90
1d910db5081bbb741f9dd3d9079a57
y: 25fdbd2f7a267f88626b5ed0d3ec687389ae01b63207c0c7fd3c86554db77f21a16fb23327fee72401087af1128e66276
9b6a8f6ce2e27bf8713297cbb41b5a4
Loading digest value OK
Signature:
r: 7977D87E4060D9AF828B146A2A0EF3DFCDC1E35AF32EBAEF5C9364E46C9DB5C2A0159D8DB0E2DAE5C25B17A45454EC733
94249DA8FE97951C7F391BB01B5EA5D
s: 2EAFC644023E36CADCD0A86D3B9C2EB028AECBA46C89EE27A5081E090A3EAC496091E3A79FBE952019E0EB0925C94A6B6
200256F96A1A38AB5E27E066541AC75
Signature load OK
Signature verification OK

Но это еще не все. Пришлось вносить изменения и в сам проект gnupg-2, например, в файл sm/sign.c были добавлены oid-ы ГОСТ-хэшей:

switch (cl->hash_algo)
        {
        case GCRY_MD_SHA1:   oid = "1.3.14.3.2.26"; break;
        case GCRY_MD_RMD160: oid = "1.3.36.3.2.1"; break;
        case GCRY_MD_SHA224: oid = "2.16.840.1.101.3.4.2.4"; break;
        case GCRY_MD_SHA256: oid = "2.16.840.1.101.3.4.2.1"; break;
        case GCRY_MD_SHA384: oid = "2.16.840.1.101.3.4.2.2"; break;
        case GCRY_MD_SHA512: oid = "2.16.840.1.101.3.4.2.3"; break;
/*ORLOV*/
	case GCRY_MD_STRIBOG256:	/* GOST R 34.11-2012, 256 bit.  */
	    oid = "1.2.643.7.1.1.2.2"; break;
	case GCRY_MD_STRIBOG512:	 /* GOST R 34.11-2012, 512 bit.  */
	    oid = "1.2.643.7.1.1.2.3"; break;
	case GCRY_MD_GOSTR3411_94:	/* GOST R 34.11-94.  */
	    oid = "1.2.643.7.1.1.2.1"; break;
/*         case GCRY_MD_WHIRLPOOL: oid = "No OID yet"; break; */
        case GCRY_MD_MD5:  /* We don't want to use MD5.  */
        case 0:            /* No algorithm found in cert.  */
        default:           /* Other algorithms.  */
          log_info (_("hash algorithm %d (%s) for signer %d not supported;"
                      " using %s\n"),
                    cl->hash_algo, oid? oid: "?", i,
                    gcry_md_algo_name (GCRY_MD_SHA1));
          cl->hash_algo = GCRY_MD_SHA1;
          oid = "1.3.14.3.2.26";
          break;
        }

После внесения всех этих изменений и установки обновленной библиотеки libgcrypt-1.6.5 и утилиты gpgsm был запущен почтовый клиент и прочитано подписанное сообщение. Результат превзошел все наши ожидания:

image

Теперь осталось разобраться с импортом сертификатов и, самое главное, – ключей. И если с импортом сертификатов все прошло хорошо, то с импортом закрытого ключа из pkcs12 пришлось потрудиться и внести изменения в подпроект agent (модуль gpg-ptotect-tool). Но когда и эти трудности были пройдены, когда были импортированы закрытые ключи (прочитать можно здесь mdf-i.blogspot.ru/2008/10/blog-post_08.html ), пришло время поклониться Клеопатре:

image

И Клеопатра благосклонно отнеслась к нашим личным (с закрытыми ключами) и не личным сертификатам. Тип сертификата здесь назван «512-битный ЕСС (закрытый ключ доступен)», но это на любителя. На втором снимке прописаны ГОСТ-овые oid-ы (префикс 1.2.643):

image

Пришло время завершать наше повествование и дать достойный ответ Thunderbird-у российской криптографией. P.S. Убедитесь (это очень важно), что gpg-agent работает:

bash-4.3$ gpg-agent --daemon --use-standard-socket
GPG_AGENT_INFO=/home/a513/.gnupg/S.gpg-agent:6283:1; export GPG_AGENT_INFO;
bash-4.3$</i>

Прежде всего надо выбрать свой личный сертификат (сертификат, у которого есть закрытый ключ), с который вы будете ставить свою ЭП:

image

Если вы нажмете кнопку «Запустить диспетчер сертификатов», то к вашим услугам будет несравненная Клеопатра! Теперь когда письмо подготовлено, сертификат для ЭП выбран — смело нанажимайте на кнопку/иконку «Подписать письмо»:

image

После этого в теле вашего письма появится, что письмо при отправке будет подписано ЭП. Нажимаем кнопку «отправить»:

image

Вводим пароль для доступа к закрытому ключу (мы его установили при импорте закрытого ключа) и нажимаем «ОК».
Ну вот и все. Но мы пока ни слова не сказали о шифровании, но это в следующий раз.
Tags:
libgcrypt, электронная подпись, сертификаты x.509, gnupg

You can't comment this post because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author's username will be hidden by an alias.