<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Форум Рутокен &mdash; pkcs11, получить публичный ключ]]></title>
	<link rel="self" href="https://forum.rutoken.ru/feed/atom/topic/1949" />
	<updated>2018-04-04T19:59:53Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.rutoken.ru/topic/1949/</id>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11705/#p11705" />
			<content type="html"><![CDATA[<p>Йес! Работает! Спасибо огромное!</p>]]></content>
			<author>
				<name><![CDATA[Юрий Ботов]]></name>
				<uri>https://forum.rutoken.ru/user/10880/</uri>
			</author>
			<updated>2018-04-04T19:59:53Z</updated>
			<id>https://forum.rutoken.ru/post/11705/#p11705</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11700/#p11700" />
			<content type="html"><![CDATA[<p>Здравствуйте, Юрий!<br />Попробуйте (между С# и JS):<br />- полностью переворачивать хеш (как и прежде);<br />- переворачивать каждую половину ключа (как и прежде);<br />- не переворачивая, переставить местами половины подписи.</p>]]></content>
			<author>
				<name><![CDATA[Алексей Караваев]]></name>
				<uri>https://forum.rutoken.ru/user/7758/</uri>
			</author>
			<updated>2018-04-04T11:32:06Z</updated>
			<id>https://forum.rutoken.ru/post/11700/#p11700</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11697/#p11697" />
			<content type="html"><![CDATA[<p>Давайте проще, без купюр <br />index.html<br /></p><div class="codebox"><pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ru&quot;&gt;
&lt;head&gt;
    &lt;title&gt;Тест рутокен&lt;/title&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;app.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;object id=&quot;pluginRutokenWEB&quot; type=&quot;application/x-rutoken&quot; width=&quot;0&quot; height=&quot;0&quot;&gt;&lt;param name=&quot;onload&quot; value=&quot;pluginit&quot; /&gt;&lt;/object&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre></div><p>app.js<br /></p><div class="codebox"><pre><code>window.onload = function () {
    // Загрузка плагина
    plugin = document.getElementById(&quot;pluginRutokenWEB&quot;);
    // Проверка плагина на валидность
    if (plugin &amp;&amp; plugin.valid) {
        // Показать версию плагина
        document.body.innerHTML += &quot;&lt;br&gt;Установлен плагин Рутокен WEB версии &quot; + plugin.get_version();
        // Проверка наличия токена в системе
        if (plugin.rtwIsTokenPresentAndOK()) {
            // теперь пробуем стандартную процедуру аутентификации rutoken
            // сначала пошлем запрос на аутентификацию:
            sendjson({ requesttype: &#039;authentificationrequest&#039;, id: plugin.rtwGetDeviceID() },
                function (e) {
                    var r = JSON.parse(e.currentTarget.response);
                    sendjson({
                        requesttype: &#039;authentificationdata&#039;,
                        signedhash: plugin.rtwSign(&#039;178&#039;, r.random),
                        publickey: plugin.rtwGetPublicKey(&#039;178&#039;)
                    },
                        function (e) { if (this.status === 200) { document.body.innerHTML += &quot;&lt;br&gt; received: &quot; + this.responseText; } }
                    );
                }
            );
        } else { window.alert(&quot;Рутокен WEB не подключен&quot;); } return;
    } else { window.alert(&quot;Установите плагин Рутокен WEB&quot;); }
};

function sendjson(jsondata,callback) {
    var xhr = new XMLHttpRequest();
    xhr.open(&#039;POST&#039;, &#039;http://localhost:6266/load.ashx&#039;, true); //  у вас тут видимо будет другой порт
    xhr.onload = callback;
    xhr.send(JSON.stringify(jsondata));
}</code></pre></div><p>load.ashx.cs<br /></p><div class="codebox"><pre><code>using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using Rutoken;
using Net.Pkcs11Interop.Common;
using Net.Pkcs11Interop.HighLevelAPI;
using RutokenPkcs11Interop;
using RutokenPkcs11Interop.Common;

namespace rutokenweb
{
    public class Load : IHttpHandler
    {
        // Шаблон для поиска закрытого ключа для цифровой подписи
        static readonly List&lt;ObjectAttribute&gt; PrivateKeyAttributes = new List&lt;ObjectAttribute&gt;
        {
            // ID пары
            new ObjectAttribute(CKA.CKA_ID, &quot;178&quot;),
            // Класс - закрытый ключ
            new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY)
        };

        // Шаблон для поиска открытого ключа для проверки цифровой подписи
        static readonly List&lt;ObjectAttribute&gt; PublicKeyAttributes = new List&lt;ObjectAttribute&gt;
        {
            // ID пары
            new ObjectAttribute(CKA.CKA_ID,&quot;178&quot;),
            // // Класс - открытый ключ
            new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY)
        };

        // словарь для представления пришедшего json запроса
        public static Dictionary&lt;String, String&gt; ext = new Dictionary&lt;String, String&gt;();
        public static string userhash = &quot;&quot;;

        public void ProcessRequest(HttpContext context)
        {
            HttpResponse response = context.Response;
            // переводим запрос в строку
            string ss = GetAsString(context);
            // полученную json строку превращаем в словарь C#
            JsonToDic(ss);

            switch(ext[&quot;requesttype&quot;])
            {
                case &quot;authentificationrequest&quot;:
                    userhash = RutokenWeb.GetRandomHash();
                    response.Write(&quot;{\&quot;random\&quot;:\&quot;&quot; + userhash + &quot;\&quot;}&quot;);
                    break;
                case &quot;authentificationdata&quot;:
                    bool Auth = RutokenWeb.CheckSignature(ext[&quot;signedhash&quot;], userhash, ext[&quot;publickey&quot;]);
                    if (Auth) { response.Write(&quot;&lt;br&gt;Auth OK&quot;); }
                    else { response.Write(&quot;&lt;br&gt;Auth none&quot;); }

                    using (var pkcs11 = new Pkcs11(Settings.RutokenEcpDllDefaultPath, Settings.OsLockingDefault))
                    {
                        Console.WriteLine(&quot;Checking tokens available&quot;);
                        Slot slot = Helpers.GetUsableSlot(pkcs11);
                        List&lt;CKM&gt; mechanisms = slot.GetMechanismList();
                        bool isGostR3410Supported = mechanisms.Contains((CKM)Extended_CKM.CKM_GOSTR3410);
                        bool isGostR3411Supported = mechanisms.Contains((CKM)Extended_CKM.CKM_GOSTR3411);
                        using (Session session = slot.OpenSession(false))
                        {
                            session.Login(CKU.CKU_USER, &quot;12345678&quot;);

                            List&lt;ObjectHandle&gt; privateKeys = session.FindAllObjects(PrivateKeyAttributes);
                            List&lt;ObjectHandle&gt; publicKeys = session.FindAllObjects(PublicKeyAttributes);

                            byte[] hash = StringToByteArray(userhash);

                            // Инициализация операции подписи данных по алгоритму ГОСТ Р 34.10-2001
                            var signMechanism = new Mechanism((uint)Extended_CKM.CKM_GOSTR3410);

                            // Подписать данные
                            byte[] signature = session.Sign(signMechanism, privateKeys[0], hash);

                            // собственная проверка
                            session.Verify(signMechanism, publicKeys[0], hash, signature, out bool isSignatureValid);

                            // преобразуем подписанный хэш в строку
                            string sig1 = ByteArrayToString(signature);
                            // конвертим строку
                            string sig = Hash32Convert(sig1);

                            // читаем открытый ключ
                            var x = session.GetAttributeValue(publicKeys[0], new List&lt;CKA&gt; { CKA.CKA_VALUE });
                            // в строку
                            var y = ByteArrayToString( x[0].GetValueAsByteArray());
                            // конвертим строку
                            var z = Key64Convert(y);

                            bool signed = RutokenWeb.CheckSignature(sig, userhash, z);
                        }
                    }
                    break;
                default: break;
            }
            ext.Clear();
        }

        public string GetAsString(HttpContext cnt)
        {
            string o = &quot;&quot;;
            System.IO.Stream s = cnt.Request.GetBufferedInputStream();
            while (true) { int c = s.ReadByte(); if (c &lt; 0) break; else o += ((char)c); }
            return o;
        }

        public void JsonToDic(string j)
        {
            Regex r = new Regex(&quot;\&quot;([^\&quot;]+)\&quot;:\&quot;([^\&quot;]+)\&quot;&quot;, RegexOptions.Singleline);
            Match m = r.Match(j);
            while (m.Success) { ext.Add(m.Groups[1].ToString(), m.Groups[2].ToString()); m = m.NextMatch(); }
        }

        public string ByteArrayToString(byte[] a)
        {
            StringBuilder o = new StringBuilder(a.Length * 2);
            for (int i = 0; i &lt; a.Length; i++) o.Append(a[i].ToString(&quot;x2&quot;));
            return o.ToString();
        }

        public byte[] StringToByteArray(string s)
        {
            string ss = s.ToUpper();
            byte[] o = new byte[s.Length / 2];
            for (int i = 0; i &lt; s.Length / 2; i++) o[i] = (byte)int.Parse(s.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
            return o;
        }

        public string Key64Convert(string PKCSKey)
        {
            string JSKey = &quot;&quot;;
            for (var i = 31; i &gt;= 0; i--) { JSKey += PKCSKey[2 * i]; JSKey += PKCSKey[2 * i + 1]; }
            for (var i = 63; i &gt;= 32; i--) { JSKey += PKCSKey[2 * i]; JSKey += PKCSKey[2 * i + 1]; }
            return JSKey;
        }

        public string BigToLittle(string s)
        {
            string o = &quot;&quot;;
            for (var i = 0; i &lt; s.Length/8; i++) {
                o += s[8 * i + 6]; o += s[8 * i + 7]; o += s[8 * i + 4]; o += s[8 * i + 5];
                o += s[8 * i + 2]; o += s[8 * i + 3]; o += s[8 * i]; o += s[8 * i + 1];
            }
            return o;
        }

        public string Hash32Convert(string s)
        {
            string o = &quot;&quot;;
            for (var i = (s.Length)/2-1; i &gt;= 0; i--) { o += s[2 * i]; o += s[2 * i + 1]; }
            return o;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

    public static class Helpers
    {
        public static Slot GetUsableSlot(Pkcs11 pkcs11)
        {
            // Получить список слотов c подключенными токенами
            List&lt;Slot&gt; slots = pkcs11.GetSlotList(true);

            // Проверить, что слоты найдены
            if (slots == null)
                throw new NullReferenceException(&quot;No available slots&quot;);

            // Проверить, что число слотов больше 0
            if (slots.Count &lt;= 0)
                throw new InvalidOperationException(&quot;No available slots&quot;);

            // Получить первый доступный слот
            Slot slot = slots[0];

            return slot;
        }

        public static void PrintByteArray(byte[] array)
        {
            var hexString = new StringBuilder();
            var width = 16;
            int byteCounter = 1;
            foreach (var item in array)
            {
                hexString.AppendFormat(&quot; 0x{0:x2}&quot;, item);
                if (byteCounter == width)
                {
                    hexString.AppendLine();
                    byteCounter = 0;
                }
                byteCounter++;
            }

            Console.WriteLine(hexString);
        }
    }
}</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Юрий Ботов]]></name>
				<uri>https://forum.rutoken.ru/user/10880/</uri>
			</author>
			<updated>2018-04-03T17:05:16Z</updated>
			<id>https://forum.rutoken.ru/post/11697/#p11697</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11696/#p11696" />
			<content type="html"><![CDATA[<p>Подписывается именно то что проверяется, просто хотел &quot;внести единообразие&quot; и в процессе накосячил: на самом деле userhash - строка, а hash - байтовый массив, а я их для примера переименовывал &quot;во что нибудь одно&quot;. Причем там где вы указали проверка проходит. Исправил в предыдущем топике, теперь везде userhash, но все должны понимать что это в зависимости от места где нужно - строка, а где нужно массив байтов.</p><p><em>И какое всё-таки хеш-значение подписывается в C#?</em> - в C# подписывается массив байт полученный из строки userhash</p>]]></content>
			<author>
				<name><![CDATA[Юрий Ботов]]></name>
				<uri>https://forum.rutoken.ru/user/10880/</uri>
			</author>
			<updated>2018-04-03T16:39:31Z</updated>
			<id>https://forum.rutoken.ru/post/11696/#p11696</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11695/#p11695" />
			<content type="html"><![CDATA[<p>Проясните, пожалуйста, почему подписывается userhash, а в проверке участвует hash:<br /></p><div class="quotebox"><blockquote><p>(C#)byte[] signature = session.Sign(signMechanism, privateKeys[0], userhash);<br />Получаем:<br />24282daa267ad10ea9340f68dae9db82375e593376cbd46f654a713ffcdb7cb1d9c89bc185138802a42aa02e2c8f516abdd9aefb4455f33c04c9ac3d6b35fbbc<br />Проверяем средствами SDK csharp:<br />(C#)session.Verify(signMechanism, publicKeys[0], hash, signature, out bool isSignatureValid) -&gt; true</p></blockquote></div><p> ?</p><p>И какое всё-таки хеш-значение подписывается в C#?</p>]]></content>
			<author>
				<name><![CDATA[Алексей Караваев]]></name>
				<uri>https://forum.rutoken.ru/user/7758/</uri>
			</author>
			<updated>2018-04-03T13:19:58Z</updated>
			<id>https://forum.rutoken.ru/post/11695/#p11695</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11691/#p11691" />
			<content type="html"><![CDATA[<p>Не пошло.</p><p>Вот так создаю хэш:<br />(C#)userhash = RutokenWeb.GetRandomHash();<br />Хэш:<br />d259f30e4fd9761b3de38b58e57f2038455dc41d0bcc46377bb8cf9c225ebfc8</p><p>Хэш подписанный в браузере,&#039;178&#039;- имя контейнера:<br />(JS)plugin.rtwSign(&#039;178&#039;, userhash)<br />FAF35341EA01FF7F1624FE069C0BA2FFF722D450A2059FF3B888B877E8562A8D0F42A019472DF31ABDF8E63C52E2B57751F256D19F28A3FCC1A3F0BDD37281DE<br />Использованный открытый ключ:<br />(JS)plugin.rtwGetPublicKey(&#039;178&#039;)<br />743FBDA620C5050F4E03FFA83DB433DB712A14F571065680CFC9F5E77481C861E13101223A079FB9117A70A973F9588D2C831CB3EA1663C8465EEB6CCC6FF568</p><p>результат:<br />(C#)RutokenWeb.CheckSignature(signedhash, userhash, publickey) -&gt; true</p><p>Теперь подписываем средствами SDK csharp:<br />(C#)List&lt;ObjectHandle&gt; privateKeys = session.FindAllObjects(PrivateKeyAttributes);<br />(C#)var signMechanism = new Mechanism((uint)Extended_CKM.CKM_GOSTR3410);<br />(C#)byte[] signature = session.Sign(signMechanism, privateKeys[0], userhash);<br />Получаем:<br />24282daa267ad10ea9340f68dae9db82375e593376cbd46f654a713ffcdb7cb1d9c89bc185138802a42aa02e2c8f516abdd9aefb4455f33c04c9ac3d6b35fbbc<br />Проверяем средствами SDK csharp:<br />(C#)session.Verify(signMechanism, publicKeys[0], userhash, signature, out bool isSignatureValid) -&gt; true<br />Достаем открытый ключ:<br />(C#)session.GetAttributeValue(publicKeys[0], new List&lt;CKA&gt; { CKA.CKA_VALUE })[0].GetValueAsByteArray()<br />61c88174e7f5c9cf80560671f5142a71db33b43da8ff034e0f05c520a6bd3f7468f56fcc6ceb5e46c86316eab31c832c8d58f973a9707a11b99f073a220131e1<br />Преобразуем его, получаем:<br />743fbda620c5050f4e03ffa83db433db712a14f571065680cfc9f5e77481c861e13101223a079fb9117a70a973f9588d2c831cb3ea1663c8465eeb6ccc6ff568<br />После преобразования он совпадает с полученным из JS.</p><p>Проверяем средствами RutokenWeb:<br />(C#)RutokenWeb.CheckSignature(signature, userhash, publickey) -&gt; false</p><p>(не показываю преобразований из массива байт в строку и обратно - они разумеется есть там где необходимо)</p>]]></content>
			<author>
				<name><![CDATA[Юрий Ботов]]></name>
				<uri>https://forum.rutoken.ru/user/10880/</uri>
			</author>
			<updated>2018-04-03T07:58:36Z</updated>
			<id>https://forum.rutoken.ru/post/11691/#p11691</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11684/#p11684" />
			<content type="html"><![CDATA[<p>Добрый день!<br />Можно попробовать не переворачивать хеш, то есть использовать одно и то же значение в плагине и csharp.<br />Если проверка подписи и так не будет пройдена, прошу выслать контрольные данные до каких-либо переворачиваний: <br />- публичный ключ, хеш, соответствующая им подпись из плагина;<br />- публичный ключ, хеш, соответствующая им подпись из приложения csharp.</p>]]></content>
			<author>
				<name><![CDATA[Алексей Караваев]]></name>
				<uri>https://forum.rutoken.ru/user/7758/</uri>
			</author>
			<updated>2018-04-02T08:58:18Z</updated>
			<id>https://forum.rutoken.ru/post/11684/#p11684</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11675/#p11675" />
			<content type="html"><![CDATA[<p>Для простоты понимания прилагаю функции на которые ссылаюсь: <br /></p><div class="codebox"><pre><code>       public string ByteArrayToString(byte[] a)
        {
            StringBuilder o = new StringBuilder(a.Length * 2);
            for (int i = 0; i &lt; a.Length; i++) o.Append(a[i].ToString(&quot;x2&quot;));
            return o.ToString();
        }

        public byte[] StringToByteArray(string s)
        {
            string ss = s.ToUpper();
            byte[] o = new byte[s.Length / 2];
            for (int i = 0; i &lt; s.Length / 2; i++) o[i] = (byte)int.Parse(s.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
            return o;
        }

        public string Key64Convert(string PKCSKey)
        {
            string JSKey = &quot;&quot;;
            for (var i = 31; i &gt;= 0; i--) { JSKey += PKCSKey[2 * i]; JSKey += PKCSKey[2 * i + 1]; }
            for (var i = 63; i &gt;= 32; i--) { JSKey += PKCSKey[2 * i]; JSKey += PKCSKey[2 * i + 1]; }
            return JSKey;
        }

        public string Hash32Convert(string s)
        {
            string o = &quot;&quot;;
            for (var i = (s.Length)/2-1; i &gt;= 0; i--) { o += s[2 * i]; o += s[2 * i + 1]; }
            return o;
        }</code></pre></div><p>Убрал из них не имеющие отношения к основной функции проверки (для наглядности)</p>]]></content>
			<author>
				<name><![CDATA[Юрий Ботов]]></name>
				<uri>https://forum.rutoken.ru/user/10880/</uri>
			</author>
			<updated>2018-03-27T11:54:52Z</updated>
			<id>https://forum.rutoken.ru/post/11675/#p11675</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11674/#p11674" />
			<content type="html"><![CDATA[<p>Ок, если проверка не срабатывает и вы уверены что данные подаете правильно и одинаково подписываете, то вопрос остается в том, как правильно передавать подпись на проверку.<br />Спасибо за подробное описание того, что вы делаете - мы постараемся разобраться и подсказать.</p>]]></content>
			<author>
				<name><![CDATA[Кирилл Мещеряков]]></name>
				<uri>https://forum.rutoken.ru/user/6786/</uri>
			</author>
			<updated>2018-03-27T11:44:08Z</updated>
			<id>https://forum.rutoken.ru/post/11674/#p11674</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11673/#p11673" />
			<content type="html"><![CDATA[<p>В том то и дело, что RutokenWeb.CheckSignature(sig, userhash, z); возвращает false. То есть ситуация такая: один и тот же хэш, один и тот-же public key одного и того же контейнера одного и того же RutokenЭЦП.<br />Вариант с подписью хэша plugin.rtwSign(&#039;контейнер&#039;, хэш), потом на сервере RutokenWeb.CheckSignature(подписанныйхэш, хэш, открытыйключ) =&gt; true.<br />Вариант чистого sdk csharp: <br />session.Login(CKU.CKU_USER, &quot;12345678&quot;);<br />List&lt;ObjectHandle&gt; privateKeys = session.FindAllObjects(PrivateKeyAttributes);<br />List&lt;ObjectHandle&gt; publicKeys = session.FindAllObjects(PublicKeyAttributes);<br />byte[] hasharray = StringToByteArray(хэш));<br />var signMechanism = new Mechanism((uint)Extended_CKM.CKM_GOSTR3410);<br />byte[] signature = session.Sign(signMechanism, privateKeys[0], hasharray);<br />bool isSignatureValid = false;<br />session.Verify(signMechanism, publicKeys[0], hasharray, signature, out isSignatureValid);<br />isSignatureValid =&gt; true.<br />А вариант при подписывании при помощи sdk csharp и проверке с помощью rutokenweb - не работает, вот он:<br />session.Login(CKU.CKU_USER, &quot;12345678&quot;);<br />List&lt;ObjectHandle&gt; privateKeys = session.FindAllObjects(PrivateKeyAttributes);<br />List&lt;ObjectHandle&gt; publicKeys = session.FindAllObjects(PublicKeyAttributes);<br />byte[] hasharray = StringToByteArray(Hash32Convert(хэш)); // переворачиваем хэш<br />var signMechanism = new Mechanism((uint)Extended_CKM.CKM_GOSTR3410);<br />byte[] signature = session.Sign(signMechanism, privateKeys[0], hasharray);<br />// преобразуем подписанный хэш в строку<br />string sig1 = ByteArrayToString(signature);<br />// конвертим строку<br />string sig = Key64Convert(sig1); // переворачиваю 2 32 байтных слова как описано в топике<br />// читаем открытый ключ<br />var x = session.GetAttributeValue(publicKeys[0], new List&lt;CKA&gt; { CKA.CKA_VALUE });<br />// в строку<br />string y = ByteArrayToString( x[0].GetValueAsByteArray());<br />// конвертим строку<br />string z = Key64Convert(y); // переворачиваю 2 32 байтных слова как описано в топике</p><p>RutokenWeb.CheckSignature(sig, хэш, z) =&gt; false</p><p>При этом z = public key имеет тот же вид что и в первом случае, хэш тоже. Вопрос: как преобразовать подписанный хэш и надо ли переворачивать изначальный хэш при подписывании</p>]]></content>
			<author>
				<name><![CDATA[Юрий Ботов]]></name>
				<uri>https://forum.rutoken.ru/user/10880/</uri>
			</author>
			<updated>2018-03-27T11:35:07Z</updated>
			<id>https://forum.rutoken.ru/post/11673/#p11673</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11672/#p11672" />
			<content type="html"><![CDATA[<p>Добрый день, подпись по ГОСТу недетерминированная, то есть 2 операции подписи одного и того же хеша на одном и том же приватном ключе дадут 2 совершенно разные подписи. <br />Вы сможете проверить правильность работы вашей криптосистемы только операцией проверки подписи, очевидно что она должна вернуть true для всех ваших подписей, хоть они и по разному внешне выглядят.</p>]]></content>
			<author>
				<name><![CDATA[Кирилл Мещеряков]]></name>
				<uri>https://forum.rutoken.ru/user/6786/</uri>
			</author>
			<updated>2018-03-27T11:02:53Z</updated>
			<id>https://forum.rutoken.ru/post/11672/#p11672</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11666/#p11666" />
			<content type="html"><![CDATA[<p>Очевидное &quot;перевернуть 32 байта хеша и перевернуть 64 байта подписанного хэша(целиком или по 32)&quot; - не работает.</p>]]></content>
			<author>
				<name><![CDATA[Юрий Ботов]]></name>
				<uri>https://forum.rutoken.ru/user/10880/</uri>
			</author>
			<updated>2018-03-26T20:51:09Z</updated>
			<id>https://forum.rutoken.ru/post/11666/#p11666</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/11665/#p11665" />
			<content type="html"><![CDATA[<p>Задача: авторизация вместе с вэб пользователями на сервере с rutoken web из клиента автомата на C#. Тоже столкнулся с тем что ключи в PKCS11 и rutokenweb отличаются :) и благодаря этому топику решил эту проблему... НО!&nbsp; Возникла вторая проблема: один и тот-же хэш подписанный в plugin.rtwSign(JS) и в session.Sign(signMechanism, privateKeys[0], hash); (C#) дают разные результаты! Видимо тоже где то надо что то перевернуть... Не подскажете?</p>]]></content>
			<author>
				<name><![CDATA[Юрий Ботов]]></name>
				<uri>https://forum.rutoken.ru/user/10880/</uri>
			</author>
			<updated>2018-03-26T18:40:50Z</updated>
			<id>https://forum.rutoken.ru/post/11665/#p11665</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/6530/#p6530" />
			<content type="html"><![CDATA[<p>Спасибо. В этом случае это имеет смысл.</p>]]></content>
			<author>
				<name><![CDATA[929121]]></name>
				<uri>https://forum.rutoken.ru/user/7927/</uri>
			</author>
			<updated>2013-08-28T09:03:31Z</updated>
			<id>https://forum.rutoken.ru/post/6530/#p6530</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: pkcs11, получить публичный ключ]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/6529/#p6529" />
			<content type="html"><![CDATA[<p>Как <a href="http://ru.wikipedia.org/wiki/%D0%93%D0%9E%D0%A1%D0%A2_%D0%A0_34.10-2012">известно</a>, открытым ключом в алгоритме ГОСТ 34.10 является точка эллиптической кривой Q=(x,y), где x и y -- 32х-байтные числа. В PKCS11 принято представление чисел в <a href="http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D0%BA_%D0%B1%D0%B0%D0%B9%D1%82%D0%BE%D0%B2">формате</a> little-endian, в то время как в плагине Rutoken Web -- в формате big-endian. Этим и объясняется необходимость преобразования.</p>]]></content>
			<author>
				<name><![CDATA[Евгений Мироненко]]></name>
				<uri>https://forum.rutoken.ru/user/8673/</uri>
			</author>
			<updated>2013-08-28T08:50:49Z</updated>
			<id>https://forum.rutoken.ru/post/6529/#p6529</id>
		</entry>
</feed>
