<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Форум Рутокен &mdash; Рутокен ЭЦП 3.0 с pki-core (C++) и OpenSSL]]></title>
	<link rel="self" href="https://forum.rutoken.ru/feed/atom/topic/4103/" />
	<updated>2023-12-01T06:57:53Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.rutoken.ru/topic/4103/</id>
		<entry>
			<title type="html"><![CDATA[Re: Рутокен ЭЦП 3.0 с pki-core (C++) и OpenSSL]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/22275/#p22275" />
			<content type="html"><![CDATA[<p>Спасибо за оперативную помощь!</p>]]></content>
			<author>
				<name><![CDATA[nicetas.matthias]]></name>
				<uri>https://forum.rutoken.ru/user/14340/</uri>
			</author>
			<updated>2023-12-01T06:57:53Z</updated>
			<id>https://forum.rutoken.ru/post/22275/#p22275</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Рутокен ЭЦП 3.0 с pki-core (C++) и OpenSSL]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/22257/#p22257" />
			<content type="html"><![CDATA[<p>Добрый день!<br /></p><div class="quotebox"><blockquote><p>Как вытащить непосредственно подписанные данные из экземпляра rutoken::pkicore::cms::SignedData (в виде строки или байтового массива, значения не имеет).</p></blockquote></div><p>Такого API в pki-core на данный момент нет. Можем предложить вам использовать detached CMS, когда исходный документ и файл с ЭП - это разные файлы. Еще вариант - использовать API OpenSSL для парсинга attached CMS.</p><p>В целом будем рады узнать в hotline@rutoken.ru больше о вашем проекте/продукте.</p>]]></content>
			<author>
				<name><![CDATA[Павел Анфимов]]></name>
				<uri>https://forum.rutoken.ru/user/7338/</uri>
			</author>
			<updated>2023-11-30T10:23:39Z</updated>
			<id>https://forum.rutoken.ru/post/22257/#p22257</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Рутокен ЭЦП 3.0 с pki-core (C++) и OpenSSL]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/22255/#p22255" />
			<content type="html"><![CDATA[<p>Добрый день! <br />Извиняюсь, мой недосмотр. Добавил <strong>-CAfile </strong> и все заработало без <strong>-noverify</strong>.<br />Но вопрос по поводу того как вытащить данные в программу остается</p>]]></content>
			<author>
				<name><![CDATA[nicetas.matthias]]></name>
				<uri>https://forum.rutoken.ru/user/14340/</uri>
			</author>
			<updated>2023-11-30T10:00:38Z</updated>
			<id>https://forum.rutoken.ru/post/22255/#p22255</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Рутокен ЭЦП 3.0 с pki-core (C++) и OpenSSL]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/22254/#p22254" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>nicetas.matthias пишет:</cite><blockquote><p>нужно добавить флаг -noverify, иначе ругается на самоподписанный сертификат</p></blockquote></div><p>Добрый день!</p><p>Это странно. Указан **-CAfile test/cert.pem**, то есть сертификат указан как доверенный, поэтому **-noverify** требоваться не должен: сертификат подписанта по цепочке должен успешно проверяться.</p>]]></content>
			<author>
				<name><![CDATA[Евгений Мироненко]]></name>
				<uri>https://forum.rutoken.ru/user/8673/</uri>
			</author>
			<updated>2023-11-30T09:13:48Z</updated>
			<id>https://forum.rutoken.ru/post/22254/#p22254</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Рутокен ЭЦП 3.0 с pki-core (C++) и OpenSSL]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/22253/#p22253" />
			<content type="html"><![CDATA[<p>Спасибо! Это помогло, с небольшим уточнением что в команде проверки подписи OpenSSL нужно добавить флаг <strong>-noverify</strong>, иначе ругается на самоподписанный сертификат, получается так:<br /></p><div class="codebox"><pre><code>openssl cms -engine rtengine -verify -certfile test/cert.pem -CAfile test/cert.pem -in test/signed_message.txt -inform der -noverify</code></pre></div><p>Еще остается вопрос как вытащить непосредственно подписанные данные из экземпляра <strong>rutoken::pkicore::cms::SignedData</strong> (в виде строки или байтового массива, значения не имеет). Или придется руками парсить файл?</p>]]></content>
			<author>
				<name><![CDATA[nicetas.matthias]]></name>
				<uri>https://forum.rutoken.ru/user/14340/</uri>
			</author>
			<updated>2023-11-30T08:50:33Z</updated>
			<id>https://forum.rutoken.ru/post/22253/#p22253</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Рутокен ЭЦП 3.0 с pki-core (C++) и OpenSSL]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/22246/#p22246" />
			<content type="html"><![CDATA[<p><strong>nicetas.matthias</strong>, </p><p>Продукт pki-core-cpp пока не поддерживают парамсеты ТК26 для ключей ГОСТ34.10-2012. Добавление поддержки планируется в начале будущего года.</p><p>Пока можно использовать другие парамсеты, которые также допускаются для ключей ГОСТ-2012.</p><p>Для этого: <br />0) Использовать rtengine: <a href="https://www.rutoken.ru/support/download/openssl/">https://www.rutoken.ru/support/download/openssl/</a><br />1) Генерация ключа и самоподписанного сертификата:<br /></p><div class="codebox"><pre><code>./openssl genpkey -out &quot;test/keyfile.key&quot; -algorithm gost2012_256 -pkeyopt paramset:id-GostR3410-2001-CryptoPro-A-ParamSet -engine rtengine

./openssl req -key &quot;test/keyfile.key&quot; -new -x509 -days 999 -subj &#039;/CN=test/&#039; -outform DER -out &quot;test/cert.der&quot; -engine rtengine

./openssl x509 -inform der -in test/cert.der -out test/cert.pem -engine rtengine</code></pre></div><p>2) подписание</p><div class="codebox"><pre><code>./openssl cms -sign -inkey &quot;test/keyfile.key&quot; -signer test/cert.pem -in test/message.txt -nosmimecap -nodetach -outform DER -out test/signed_message.txt -nocerts -engine rtengine</code></pre></div><br /><p>2.1) проверка подписи с помощью OpenSSL<br /></p><div class="codebox"><pre><code>./openssl cms -engine rtengine -verify -certfile test/cert.pem -CAfile test/cert.pem -in test/signed_message.txt -inform der
# OK </code></pre></div><p>3) Далее пример с импортом сертификата на токен (тогда его не надо указывать в VerifyParams) должен сработать. Cертификат на токене используется как сертификат доверенного УЦ, поэтому пользовательский сертификат все равно придется добавлять в VerifyParams. Для самоподписанного сертификата это одно и тоже.<br /></p><div class="codebox"><pre><code>/*************************************************************************
* Rutoken                                                                *
* Copyright (c) 2003-2023, Aktiv-Soft JSC. All rights reserved.          *
* Подробная информация:  http://www.rutoken.ru                           *
*------------------------------------------------------------------------*
* Данный пример демонстрирует проверку подписи CMS сообщения с помощью   *
* pkicore. CMS сообщение с данными и сертификатом читается из файла      *
* signed_data. CA сертификат читается из файла ca.pem. Для создания CMS  *
* сообщения можно воспользоваться примером CmsSign.                      *
*************************************************************************/

#include &lt;common.h&gt;

using namespace std;
using namespace rutoken::pkicore;

int main()
{
    try {
        cout &lt;&lt; boolalpha;

        /**********************************************************************
        * Инициализируем pkicore, передав путь до директории с библиотекой    *
        * rtPKCS11ECP.                                                        *
        **********************************************************************/
        rutoken::pkicore::initialize(&quot;.&quot;);
        SCOPE_EXIT() {
            /**********************************************************************
            * Завершаем работу с pkicore при выходе из текущего блока.            *
            **********************************************************************/
            rutoken::pkicore::deinitialize();
        };

        /**********************************************************************
        * Получаем список подключенных устройств и продолжаем работу с первым *
        * доступным устройством.                                              *
        **********************************************************************/
        auto devices = Pkcs11Device::enumerate();
        if (devices.empty()) {
            throw runtime_error(&quot;There must be at least one device connected&quot;);
        }

        auto device = move(devices.front());

        /**********************************************************************
        * Читаем файл с подписанным сообщением.                               *
        **********************************************************************/
        const auto inputFileName = &quot;test/signed_message.txt&quot;;

        cout &lt;&lt; &quot;Reading signed message from &quot; &lt;&lt; inputFileName &lt;&lt; endl;

        auto signedData = cms::SignedData::parse(readFile(inputFileName));

        /**********************************************************************
        * Читаем файл с CA сертификатом.                                      *
        **********************************************************************/
        const auto caCertFileName = &quot;test/cert.der&quot;;

        cout &lt;&lt; &quot;Reading CA certificate from &quot; &lt;&lt; caCertFileName &lt;&lt; endl;

        auto caCertBuf = readFile(caCertFileName);
        ExternalCert caCert(caCertBuf.data(), caCertBuf.size());

        device.login(&quot;12345678&quot;);
        SCOPE_EXIT(&amp;device) {
            /**********************************************************************
            * Сбрасываем права доступа при выходе из текущего блока.              *
            **********************************************************************/
            device.logout();
        };
        device.importCert(caCert, true);

        ExternalCert userCert(caCertBuf.data(), caCertBuf.size());

        /**********************************************************************
        * Проверяем подпись сообщения.                                        *
        **********************************************************************/
        cms::VerifyParams params(device, cms::VerifyParams::Flag::verifyUserCert);
        params.addUserCert(userCert);

        auto result = signedData.verify(params);
        if (result == cms::VerifyResult::success) {
            cout &lt;&lt; &quot;Correct signature&quot; &lt;&lt; endl;
        } else {
            cout &lt;&lt; &quot;Wrong signature&quot; &lt;&lt; endl;
        }
    } catch (const exception&amp; e) {
        cerr &lt;&lt; e.what() &lt;&lt; endl;
        return 1;
    }

    return 0;
}</code></pre></div><p>4) Пример без импорта сертификата на токен<br /></p><div class="codebox"><pre><code>/*************************************************************************
* Rutoken                                                                *
* Copyright (c) 2003-2023, Aktiv-Soft JSC. All rights reserved.          *
* Подробная информация:  http://www.rutoken.ru                           *
*------------------------------------------------------------------------*
* Данный пример демонстрирует проверку подписи CMS сообщения с помощью   *
* pkicore. CMS сообщение с данными и сертификатом читается из файла      *
* signed_data. CA сертификат читается из файла ca.pem. Для создания CMS  *
* сообщения можно воспользоваться примером CmsSign.                      *
*************************************************************************/

#include &lt;common.h&gt;

using namespace std;
using namespace rutoken::pkicore;

int main()
{
    try {
        cout &lt;&lt; boolalpha;

        /**********************************************************************
        * Инициализируем pkicore, передав путь до директории с библиотекой    *
        * rtPKCS11ECP.                                                        *
        **********************************************************************/
        rutoken::pkicore::initialize(&quot;.&quot;);
        SCOPE_EXIT() {
            /**********************************************************************
            * Завершаем работу с pkicore при выходе из текущего блока.            *
            **********************************************************************/
            rutoken::pkicore::deinitialize();
        };

        /**********************************************************************
        * Получаем список подключенных устройств и продолжаем работу с первым *
        * доступным устройством.                                              *
        **********************************************************************/
        auto devices = Pkcs11Device::enumerate();
        if (devices.empty()) {
            throw runtime_error(&quot;There must be at least one device connected&quot;);
        }

        auto device = move(devices.front());

        /**********************************************************************
        * Читаем файл с подписанным сообщением.                               *
        **********************************************************************/
        const auto inputFileName = &quot;test/signed_message.txt&quot;;

        cout &lt;&lt; &quot;Reading signed message from &quot; &lt;&lt; inputFileName &lt;&lt; endl;

        auto signedData = cms::SignedData::parse(readFile(inputFileName));

        /**********************************************************************
        * Читаем файл с CA сертификатом.                                      *
        **********************************************************************/
        const auto caCertFileName = &quot;test/cert.der&quot;;

        cout &lt;&lt; &quot;Reading CA certificate from &quot; &lt;&lt; caCertFileName &lt;&lt; endl;

        auto caCertBuf = readFile(caCertFileName);
        ExternalCert caCert(caCertBuf.data(), caCertBuf.size());
        ExternalCert userCert(caCertBuf.data(), caCertBuf.size());

        /**********************************************************************
        * Проверяем подпись сообщения.                                        *
        **********************************************************************/
        cms::VerifyParams params(device, cms::VerifyParams::Flag::verifyUserCert);
        params.addCaCert(caCert);
        params.addUserCert(userCert);

        auto result = signedData.verify(params);
        if (result == cms::VerifyResult::success) {
            cout &lt;&lt; &quot;Correct signature&quot; &lt;&lt; endl;
        } else {
            cout &lt;&lt; &quot;Wrong signature&quot; &lt;&lt; endl;
        }
    } catch (const exception&amp; e) {
        cerr &lt;&lt; e.what() &lt;&lt; endl;
        return 1;
    }

    return 0;
}</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Павел Анфимов]]></name>
				<uri>https://forum.rutoken.ru/user/7338/</uri>
			</author>
			<updated>2023-11-29T13:51:45Z</updated>
			<id>https://forum.rutoken.ru/post/22246/#p22246</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Рутокен ЭЦП 3.0 с pki-core (C++) и OpenSSL]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/22245/#p22245" />
			<content type="html"><![CDATA[<p>Добрый день, <strong>Павел Анфимов</strong>, !<br />Я думал что сертификаты хранимые на устройстве по-умолчанию используются при проверке подписи.</p><p>Сделал как вы написали в двух вариантах </p><p>1. Добавил сертификаты из самого токена (что мне и нужно)<br /></p><div class="codebox"><pre><code>for (auto &amp;iter : device.enumerateCerts ())
{
    auto cert = rutoken::pkicore::ExternalCert (iter.toPem ());
    verifyParams.addUserCert (cert);
}</code></pre></div><p>2. Добавил сертификат, с которым подписывал через OpenSSL из файла<br /></p><div class="codebox"><pre><code>auto сertBuf = readFile (&quot;/path/to/cert.pem&quot;);
rutoken::pkicore::ExternalCert cert (std::string (сertBuf.begin (), сertBuf.end ()));
verifyParams.addUserCert (cert);</code></pre></div><p>И другим способом<br /></p><div class="codebox"><pre><code>auto certBuf = readFile (&quot;/path/to/cert.der&quot;);
rutoken::pkicore::ExternalCert cert ((void*) certBuf.data (), certBuf.size());
verifyParams.addUserCert (cert);</code></pre></div><p>Во всех случаях все также выбрасывается исключение &quot;Bad parameters&quot;</p>]]></content>
			<author>
				<name><![CDATA[nicetas.matthias]]></name>
				<uri>https://forum.rutoken.ru/user/14340/</uri>
			</author>
			<updated>2023-11-29T11:04:58Z</updated>
			<id>https://forum.rutoken.ru/post/22245/#p22245</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Рутокен ЭЦП 3.0 с pki-core (C++) и OpenSSL]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/22244/#p22244" />
			<content type="html"><![CDATA[<p><strong>nicetas.matthias</strong>, добрый день!</p><p>Дело в том, что в CMS нет пользовательского сертификата (флаг &quot;-nocerts&quot;), и в VerifyParams он тоже не передан.<br />Поэтому необходим вызов:</p><div class="codebox"><pre><code>verifyParams.addUserCert(rutoken::pkicore::ExternalCert (certData.data (), certData.size ()));</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Павел Анфимов]]></name>
				<uri>https://forum.rutoken.ru/user/7338/</uri>
			</author>
			<updated>2023-11-29T09:59:42Z</updated>
			<id>https://forum.rutoken.ru/post/22244/#p22244</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Рутокен ЭЦП 3.0 с pki-core (C++) и OpenSSL]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/22238/#p22238" />
			<content type="html"><![CDATA[<p>Добрый день!<br />Есть задача:<br />На конечной машине (пользовательской) проверять подпись на файле с помощью импортированного самоподписанного сертификата. Важно что на конечной машине нужно пользоваться ТОЛЬКО pki-core. На моей машине (администраторской) можно пользоваться чем угодно. Обе машины на Astra Linux</p><p>Схема реализации: <br />1. На своей машине (администраторская) генерю ключевую пару:<br /></p><div class="codebox"><pre><code>openssl genpkey -out &quot;keyfile.key&quot; -algorithm gost2012_256 -pkeyopt paramset:A</code></pre></div><p>2. Выпускаю самоподписанный сертификат (в формате DER, потому что pki-core дружит только с ним, поправьте если не прав)<br /></p><div class="codebox"><pre><code>openssl req -key &quot;keyfile.key&quot; -new -x509 -days 999 -subj &#039;*SUBJ*&#039; -outform DER -out &quot;cert.der&quot;</code></pre></div><p>3. Конвертирую сертификат в PEM потому что для cms подписи OpenSSL нужен именно он (опять же поправьте если ошибаюсь)<br /></p><div class="codebox"><pre><code>openssl x509 -inform der -in cert.der -out cert.pem</code></pre></div><p>4. Подписываю файл с помощью OpenSSL<br /></p><div class="codebox"><pre><code>openssl cms -sign -inkey &quot;keyfile.key&quot; -signer cert.pem -in message.txt -nosmimecap -nodetach -outform DER -out signed_message.txt -nocerts</code></pre></div><p>5. Импортирую сертификат в формате DER в токен как доверенный<br /></p><div class="codebox"><pre><code>auto certData = readFile (&quot;/path/to/cert.der&quot;);
device.importCert (rutoken::pkicore::ExternalCert (certData.data (), certData.size ()), true);</code></pre></div><p>6. Пытаюсь верифицировать подпись на токене<br /></p><div class="codebox"><pre><code>auto signedData = rutoken::pkicore::cms::SignedData::parse (readFile (&quot;/path/to/signed_message.txt&quot;));
auto verifyParams = rutoken::pkicore::cms::VerifyParams (device);
auto result = signedData.verify (verifyParams);</code></pre></div><p>При вызове метода verify выбрасывается исключение &quot;Bad parameters&quot;</p><p>Подскажите что я делаю не так и как с этим бороться</p>]]></content>
			<author>
				<name><![CDATA[nicetas.matthias]]></name>
				<uri>https://forum.rutoken.ru/user/14340/</uri>
			</author>
			<updated>2023-11-28T12:40:49Z</updated>
			<id>https://forum.rutoken.ru/post/22238/#p22238</id>
		</entry>
</feed>
