<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Форум Рутокен &mdash; Импорт закрытого ключа Rutoken ECP 2.0]]></title>
	<link rel="self" href="https://forum.rutoken.ru/feed/atom/topic/2676/" />
	<updated>2017-08-25T17:21:38Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.rutoken.ru/topic/2676/</id>
		<entry>
			<title type="html"><![CDATA[Re: Импорт закрытого ключа Rutoken ECP 2.0]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11142/#p11142" />
			<content type="html"><![CDATA[<p>Владимир, спасибо за ответ. Значит ограничение накладывается самим токеном.<br />К слову у КриптоПро есть pkcs11 интерфейс, но похоже только для Mac и Linux платформ: /opt/cprocsp/lib/amd64/libcppkcs11.so<br />Во всяком случае Firefox, Thunderbird и OpenSC с ним работают, проблема только у IFC плагина госуслуг (описана выше). Попинаю КриптоРро и Ростелеком на предмет совместимости. Может сдвинется с мертвой точки.</p><p>У меня сертификат выдан УЦ Такском, без привязки к конкретному криптопровайдеру, но т.к. 1С умеет работать только с КриптоПро (Linux), то и сертификат установлен с использованием данного криптопровайдера. Изначально использовался Rutoken Light, но он работает либо с КриптоПро, либо с PKCS, третьего не дано.</p>]]></content>
			<author>
				<name><![CDATA[lirein]]></name>
				<uri>https://forum.rutoken.ru/user/10752/</uri>
			</author>
			<updated>2017-08-25T17:21:38Z</updated>
			<id>https://forum.rutoken.ru/post/11142/#p11142</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Импорт закрытого ключа Rutoken ECP 2.0]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11141/#p11141" />
			<content type="html"><![CDATA[<p>Добрый день, <strong>lirein</strong>.<br />Давайте разбираться.<br />Как я понял, конечная цель всех этих действий - полноценная работа в ОС GNU\Linux на сайте госуслуг.<br />Сайт госуслуги работает с КЭП, которая создана по ГОСТ 34.10. Для работы с КЭП сайт госуслуги использует плагин IFCPlugin от компании Ростелеком. Этот плагин умеет работать с 2 разными интерфейсами - CAPI и PKCS11. КриптоПро CSP - криптопровайдер, который реализует интерфейс CAPI. librtpkcs11ecps.so - библиотека, которая реализует интерфейс PKCS11. Эти интерфейсы не совместимы между собой.<br />У Вас есть токен с сертификатом в формате КриптоПро CSP. Увидеть этот сертификат через интерфейс PKCS11 невозможно. Похоже, что у Вас сертификат с извлекаемым ключом. Поэтому Вам удалось успешно сделать импорт. Теперь Вы хотите импортировать этот ключ на токен, через интерфейс PKCS11 и использовать в Linux через тот же PKCS11.</p><p>Сделать такое с Рутокен ЭЦП 2.0 у Вас не получится. Импорт ГОСТ ключей на Рутокен ЭЦП 2.0 запрещен по требованиям регулятора, сделано это внутри устройства. Редактирование OpenSC тут никак не поможет. Единственный вариант это пойти в УЦ и перевыпустить сертификат, произнеся магическую фразу &quot;Как для ЕГАИС&quot;. Тогда токен сам сгенерирует неизвлекаемые ключи и сертификат в формате PKCS11. Тогда госуслуги будут работать в Linux, но ключи будут защищены от копирования, неизвлекаемые из устройства.</p><p>Вариант номер 2. Импортировать полученный из КриптоПро сертификат и ключи на несертифицированное устройство Рутокен ЭЦП PKI. Да, Панель управления Рутокен такой импорт не поддерживает, но сам токен поддерживает. И импорт средствами того же opensc должен сработать. Если не сработает - пишите - разберемся, поможем. Будет работать в Linux на госуслугах. Хотя с юридической точки зрения это нарушение, так как в вашем сертификате прописано средство подписи СКЗИ КриптоПро CSP, и использовать подпись через другие средства запрещено.</p>]]></content>
			<author>
				<name><![CDATA[Владимир Салыкин]]></name>
				<uri>https://forum.rutoken.ru/user/10195/</uri>
			</author>
			<updated>2017-08-25T13:24:25Z</updated>
			<id>https://forum.rutoken.ru/post/11141/#p11141</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Импорт закрытого ключа Rutoken ECP 2.0]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11140/#p11140" />
			<content type="html"><![CDATA[<p>Спасибо за ответ, иморт закрытых ключей стандарта RSA осуществляется с помощью pkcs11-tool успешно, сертификаты ключа проверки электронной подписи так же привязываются, в том числе через веб портал Центра регистрации Rutoken.<br />Не осуществляется импорт ключа GOST R3410, нужные модификации для чтения ключа OpenSC произведены (возможность использования альтернативных криптопровайдеров, в т.ч. КриптоПро или Рутокен).</p><p>Задача следующая, в настоящий момент времени невозможно осуществление доступа на портал Госуслуг с использованием плагина Госуслуг IFC с использованим СКЗИ КриптоПро, в частности при подключении модуля pkcs11 в конфигурации плагина IFC, при попытке обращения к нему в журнал падает ошибка &quot;Too many events on token&quot; и сертификаты не читаются, тем не менее сам КриптоПро видится и даже рапортует о наличии в слоте сертификатов. Похоже на недоработку со стороны КриптоПро.</p><p>Экспортировать и разобрать закрытый ключ из контейнера криптопро можно как шатаными средствами (несовместимо с OpenSSL) так и через специализированную утилиту от Лисси. Rutoken PKI под ОС Windows позволяет импорт только закрытых ключей RSA включая сертификат из файлов формата pkcs12, контейнер с ключем ГОСТ не импортируется. В ОС Linux импорт сертификатов можно осуществить через NSS (например через плагин pkcs11 в Firefox) из контейнеров pkcs12, но ГОСТ сертификат при этом импортировать невозможно, даже с использованием обозревателя CryptoFox.</p><p>Собственно нужно перенести сертификат из контейнера КриптоПро на Рутокен, для обеспечения полноценной работы в ОС GNU\Linux.</p>]]></content>
			<author>
				<name><![CDATA[lirein]]></name>
				<uri>https://forum.rutoken.ru/user/10752/</uri>
			</author>
			<updated>2017-08-24T09:56:28Z</updated>
			<id>https://forum.rutoken.ru/post/11140/#p11140</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Импорт закрытого ключа Rutoken ECP 2.0]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11139/#p11139" />
			<content type="html"><![CDATA[<p>Добрый день, <strong>lirein</strong>.<br />Рутокен ЭЦП 2.0 не поддерживает импорт закрытых ключей, это требование регулятора. По очевидными причинам это ограничение сделано не на уровне PKCS11, а внутри самого устройства.</p><p>Если вам нужен импорт закрытого ключа, вы можете использовать Рутокен ЭЦП PKI.<br />Вы для каких целей хотите сделать подобный импорт?</p>]]></content>
			<author>
				<name><![CDATA[Владимир Салыкин]]></name>
				<uri>https://forum.rutoken.ru/user/10195/</uri>
			</author>
			<updated>2017-08-24T09:36:49Z</updated>
			<id>https://forum.rutoken.ru/post/11139/#p11139</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Импорт закрытого ключа Rutoken ECP 2.0]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11138/#p11138" />
			<content type="html"><![CDATA[<p>Добрый день, исправил код текущей ветки OpenSC для импорта закрытых ключей GOST R3410 в рутокен, изменения вносились согласно документации на pkcs11 (openoasis) и rutoken.</p><p>Ссылка на форк библиотеки, оттуда нужен только pkcs11_tool<br /><a href="https://github.com/Lirein/OpenSC">https://github.com/Lirein/OpenSC</a></p><p>Вызываю так:<br />./src/tools/pkcs11-tool --module /usr/lib/librtpkcs11ecp.so -l -E gost -y privkey -w key.der --slot 0 --id 65536 <br />Пробовал указывать другие механизмы, эффект одинаковый:<br />error: PKCS11 function C_CreateObject failed: rv = CKR_TEMPLATE_INCONSISTENT (0xd1)</p><p>В документации указано что ошибка модет возникать в том числе при не поддерживаемом типе ключей для импорта.</p><p>Код патча:<br /></p><div class="codebox"><pre><code>diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
index 8aa1cff..d4fe730 100644
--- a/src/tools/pkcs11-tool.c
+++ b/src/tools/pkcs11-tool.c
@@ -50,6 +50,7 @@
 #include &lt;openssl/asn1t.h&gt;
 #include &lt;openssl/rsa.h&gt;
 #include &lt;openssl/pem.h&gt;
+#include &lt;openssl/engine.h&gt;
 #if OPENSSL_VERSION_NUMBER &gt;= 0x00908000L &amp;&amp; !defined(OPENSSL_NO_EC) &amp;&amp; !defined(OPENSSL_NO_ECDSA)
 #include &lt;openssl/ec.h&gt;
 #include &lt;openssl/ecdsa.h&gt;
@@ -179,6 +180,7 @@ static const struct option options[] = {
     { &quot;usage-sign&quot;,        0, NULL,        OPT_KEY_USAGE_SIGN },
     { &quot;usage-decrypt&quot;,    0, NULL,        OPT_KEY_USAGE_DECRYPT },
     { &quot;usage-derive&quot;,    0, NULL,        OPT_KEY_USAGE_DERIVE },
+    { &quot;engine&quot;,        1, NULL,        &#039;E&#039; },
     { &quot;write-object&quot;,    1, NULL,        &#039;w&#039; },
     { &quot;read-object&quot;,    0, NULL,        &#039;r&#039; },
     { &quot;delete-object&quot;,    0, NULL,        &#039;b&#039; },
@@ -244,6 +246,7 @@ static const char *option_help[] = {
     &quot;Specify &#039;sign&#039; key usage flag (sets SIGN in privkey, sets VERIFY in pubkey)&quot;,
     &quot;Specify &#039;decrypt&#039; key usage flag (RSA only, set DECRYPT privkey, ENCRYPT in pubkey)&quot;,
     &quot;Specify &#039;derive&#039; key usage flag (EC only)&quot;,
+    &quot;Set SSL engine provider&quot;,
     &quot;Write an object (key, cert, data) to the card&quot;,
     &quot;Get object&#039;s CKA_VALUE attribute (use with --type)&quot;,
     &quot;Delete an object (use with --type cert/data/privkey/pubkey/secrkey)&quot;,
@@ -291,6 +294,7 @@ static int        opt_slot_index_set = 0;
 static CK_MECHANISM_TYPE opt_mechanism = 0;
 static int        opt_mechanism_used = 0;
 static const char *    opt_file_to_write = NULL;
+static const char *    opt_engine = NULL;
 static const char *    opt_object_class_str = NULL;
 static CK_OBJECT_CLASS    opt_object_class = -1;
 static CK_BYTE        opt_object_id[100], new_object_id[100];
@@ -529,6 +533,7 @@ int main(int argc, char * argv[])
 #endif
     int need_session = 0;
     int opt_login = 0;
+    int do_set_engine = 0;
     int do_init_token = 0;
     int do_init_pin = 0;
     int do_change_pin = 0;
@@ -536,7 +541,7 @@ int main(int argc, char * argv[])
     int action_count = 0;
     int do_generate_random = 0;
     CK_RV rv;
-
+    ENGINE *eng = NULL;
 #ifdef _WIN32
     char expanded_val[PATH_MAX];
     DWORD expanded_len;
@@ -547,24 +552,8 @@ int main(int argc, char * argv[])
         util_fatal(&quot;Cannot set FMODE to O_BINARY&quot;);
 #endif
 
-#ifdef ENABLE_OPENSSL
-#if (OPENSSL_VERSION_NUMBER &gt;= 0x00907000L &amp;&amp; OPENSSL_VERSION_NUMBER &lt; 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
-    OPENSSL_config(NULL);
-#endif
-#if OPENSSL_VERSION_NUMBER &gt;= 0x10100000L &amp;&amp; !defined(LIBRESSL_VERSION_NUMBER)
-    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS
-        | OPENSSL_INIT_ADD_ALL_CIPHERS
-        | OPENSSL_INIT_ADD_ALL_DIGESTS
-        | OPENSSL_INIT_LOAD_CONFIG,
-        NULL);
-#else
-    /* OpenSSL magic */
-    OpenSSL_add_all_algorithms();
-    OPENSSL_malloc_init();
-#endif
-#endif
     while (1) {
-        c = getopt_long(argc, argv, &quot;ILMOTa:bd:e:hi:klm:o:p:scvf:ty:w:z:r&quot;,
+        c = getopt_long(argc, argv, &quot;ILMOTa:bd:e:hi:klm:o:p:scvf:ty:w:z:rE:&quot;,
                         options, &amp;long_optind);
         if (c == -1)
             break;
@@ -612,6 +601,12 @@ int main(int argc, char * argv[])
             opt_file_to_write = optarg;
             action_count++;
             break;
+        case &#039;E&#039;:
+            need_session |= NEED_SESSION_RW;
+            do_set_engine = 1;
+            opt_engine = optarg;
+            action_count++;
+            break;
         case &#039;r&#039;:
             need_session |= NEED_SESSION_RO;
             do_read_object = 1;
@@ -841,6 +836,26 @@ int main(int argc, char * argv[])
             util_print_usage_and_die(app_name, options, option_help, NULL);
         }
     }
+#ifdef ENABLE_OPENSSL
+#if (OPENSSL_VERSION_NUMBER &gt;= 0x00907000L &amp;&amp; OPENSSL_VERSION_NUMBER &lt; 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
+    OPENSSL_config(NULL);
+#endif
+#if OPENSSL_VERSION_NUMBER &gt;= 0x10100000L &amp;&amp; !defined(LIBRESSL_VERSION_NUMBER)
+    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS
+        | OPENSSL_INIT_ADD_ALL_CIPHERS
+        | OPENSSL_INIT_ADD_ALL_DIGESTS
+        | OPENSSL_INIT_LOAD_CONFIG,
+        NULL);
+#else
+    /* OpenSSL magic */
+        if(do_set_engine) {
+          eng = ENGINE_by_id(opt_engine);
+          ENGINE_set_default(eng, ENGINE_METHOD_ALL);
+        }
+    OpenSSL_add_all_algorithms();
+    OPENSSL_malloc_init();
+#endif
+#endif
     if (optind &lt; argc) {
         util_fatal(&quot;invalid option(s) given&quot;);
     }
@@ -2415,6 +2430,8 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost)
    public keys (-type pubkey) and data objects (-type data). */
 static int write_object(CK_SESSION_HANDLE session)
 {
+        const CK_BYTE GOST_HASH_PARAMSET_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01};
+        CK_BYTE hash_paramset_encoded_oid[9];
     CK_BBOOL _true = TRUE;
     CK_BBOOL _false = FALSE;
     unsigned char contents[MAX_OBJECT_SIZE + 1];
@@ -2634,12 +2651,16 @@ static int write_object(CK_SESSION_HANDLE session)
             n_privkey_attr++;
         }
         else if (pk_type == NID_id_GostR3410_2001)   {
-            type = CKK_GOSTR3410;
+printf(&quot;Write gost key\n&quot;);
+                        memcpy(hash_paramset_encoded_oid, GOST_HASH_PARAMSET_OID, sizeof(GOST_HASH_PARAMSET_OID));
 
+            type = CKK_GOSTR3410;
             FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &amp;type, sizeof(type));
             n_privkey_attr++;
             FILL_ATTR(privkey_templ[n_privkey_attr], CKA_GOSTR3410_PARAMS, gost.param_oid.value, gost.param_oid.len);
             n_privkey_attr++;
+                        FILL_ATTR(privkey_templ[n_privkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid, sizeof(hash_paramset_encoded_oid));
+            n_privkey_attr++;
             FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len);
             /* CKA_VALUE of the GOST key has to be in the little endian order */
             rv = sc_mem_reverse(privkey_templ[n_privkey_attr].pValue, privkey_templ[n_privkey_attr].ulValueLen);
@@ -2735,6 +2756,7 @@ static int write_object(CK_SESSION_HANDLE session)
             n_pubkey_attr++;
         }
         else if (pk_type == NID_id_GostR3410_2001) {
+printf(&quot;Write gost public key&quot;);
             type = CKK_GOSTR3410;
 
             FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &amp;type, sizeof(type));
@@ -2824,6 +2846,7 @@ static int write_object(CK_SESSION_HANDLE session)
     }
 
     if (n_privkey_attr) {
+                printf(&quot;Create object with gost key\n&quot;);
         rv = p11-&gt;C_CreateObject(session, privkey_templ, n_privkey_attr, &amp;privkey_obj);
         if (rv != CKR_OK)
             p11_fatal(&quot;C_CreateObject&quot;, rv);</code></pre></div>]]></content>
			<author>
				<name><![CDATA[lirein]]></name>
				<uri>https://forum.rutoken.ru/user/10752/</uri>
			</author>
			<updated>2017-08-24T04:07:34Z</updated>
			<id>https://forum.rutoken.ru/post/11138/#p11138</id>
		</entry>
</feed>
