(2015-07-10 09:43:19 отредактировано Zaharatot)

Рутокен, ЭЦП и C#

Здравствуйте. Заранее оговорюсь, что с токенами до этого дел не имел, поэтому мои вопросы могут быть несколько глупыми, или в корне не верными, поэтому прошу поправить меня, если что.
У меня есть программа на C#, генерирующая xml файлы. Эти файлы нужно подписывать ЭЦП, при помощи токена. Вопрос такой - можно - ли использовать стандартные C#-библиотеки, для подписывания xml файлов, или же работать будет только ваша SDK?
Вот мой текущий код(с токеном пока не проверялся):

        /// <summary>
        /// Подписывание xml-файла
        /// </summary>
        /// <param name="path">Путь к подписываемому файлу</param>
        public bool SignXml(string path)
        {
            CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";            

            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
            if (rsaKey.CspKeyContainerInfo.HardwareDevice)
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.PreserveWhitespace = true;
                xmlDoc.Load(path);

                SignedXml signedXml = new SignedXml(xmlDoc);
                signedXml.SigningKey = rsaKey;

                Reference reference = new Reference();
                reference.Uri = "";

                XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
                reference.AddTransform(env);
                signedXml.AddReference(reference);
                signedXml.ComputeSignature();
                XmlElement xmlDigitalSignature = signedXml.GetXml();
                xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));

                xmlDoc.Save(path);
                return true;
            }
            else
                MessageBox.Show("Вставьте USB-Токен, для подписания документа.", "Ошибка подписывания", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            return false;
        }

Re: Рутокен, ЭЦП и C#

Добрый день.
Примеров под C# у нас нет, поэтому трудно что-то конкретное подсказать.
Но в целом, ваш ход мысли правильный, нужно лишь вместо программных криптопровайдеров Microsoft использовать наш аппаратный криптопровайдер Aktiv.

Re: Рутокен, ЭЦП и C#

Кирилл Мещеряков, спасибо большое, за ответ. Как только у меня появится на руках токен я буду разбираться с этим вопросом. Как тошлько что-то прояснится, я отпишусь.
P.S. Ещё бы знать, как активировать, этот ваш Aktiv... Но в какую сторону копать я знаю, в буду смотреть МСДН, когда уже сам токен будет...

Re: Рутокен, ЭЦП и C#

Стандартная функция по каким-то причинам не хочет цепляться к токену, по этому я решил делать через C# - обёртку для стандартной библиотеки РуТокена. И сразу же возникла проблема - примеров работы с обёрткой просто нету, а примеры из этой статьи  - http://habrahabr.ru/company/aktiv-company/blog/249723/
Заточены под C++, и вызывают только большее количество вопросов.
Я пробую подклдючиться к токену, через обёртку:

            CryptoCore Crypto = CryptoCore.getInstance();
            LongVector devises = Crypto.enumerateDevices();

            foreach (var dv in devises)
            {
                DeviceInfo de = Crypto.getDeviceInfo(dv);
                switch (de.type)
                {
                    case 0:
                        listBox1.Items.Add("Unknown"); break;
                    case 1:
                        listBox1.Items.Add("Rutoken ECP"); break;
                    case 2:
                        listBox1.Items.Add("Rutoken WEB"); break;
                    case 3:
                        listBox1.Items.Add("Rutoken PINPAD IN"); break;
                    case 4:
                        listBox1.Items.Add("KAZTOKEN"); break;
                    case 5:
                        listBox1.Items.Add("Rutoken PINPAD2");break;
                }
            }

Но не совсем понимаю, чем инициализовывать cryptoCore. В статье на хабре она инициализируется строкой, а тут при

new CryptoCore() 

требует переменной типа intPtr, и булевой. Подскажите пожалуйста, хотябы примерно, как проводить инициализацию.

(2015-07-25 18:43:58 отредактировано Zaharatot)

Re: Рутокен, ЭЦП и C#

Так, относительно начинаю разбираться, но при попытке запуска кода(который сверху) теперь выдаёт ошибку:

An unhandled exception of type 'System.ApplicationException' occurred in testConsole.exe
Additional information: 101:error:80001401:Vendor defined:PKCS11_CTX_load:Unable to load PKCS#11 module

rtPKCS11ECP.dll и rtpkicoreCSharp.dll закинул в папку к exe-шнику программы.

Re: Рутокен, ЭЦП и C#

Насколько я понял, библиотека rtpkicoreCSharp не может найти библиотеку PKCS#11, хотя файл rtPKCS11ECP лежит рядом.

Re: Рутокен, ЭЦП и C#

Чуть-чуть поменял код, и прошлая ошибка выводиться перестала, зато появилась новая:

        static void cryptKey()
        {
            CryptoCore Crypto = new CryptoCore(rtpkicorePINVOKE.CryptoCore_getInstance(), true);
            LongVector devises = Crypto.enumerateDevices();

            foreach (var dv in devises)
            {
                DeviceInfo de = Crypto.getDeviceInfo(dv);
                switch (de.type)
                {
                    case 0:
                        Console.WriteLine("Unknown"); break;
                    case 1:
                        Console.WriteLine("Rutoken ECP"); break;
                    case 2:
                        Console.WriteLine("Rutoken WEB"); break;
                    case 3:
                        Console.WriteLine("Rutoken PINPAD IN"); break;
                    case 4:
                        Console.WriteLine("KAZTOKEN"); break;
                    case 5:
                        Console.WriteLine("Rutoken PINPAD2"); break;
                }
            }


            Console.ReadLine();
            Console.ReadLine();
        }
/*
Ошибка выскакивает на строке - LongVector devises = Crypto.enumerateDevices();
An unhandled exception of type 'System.AccessViolationException' occurred in testConsole.exe
Additional information: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
*/

Re: Рутокен, ЭЦП и C#

Ну, судя по тому, что
rtpkicorePINVOKE.CryptoCore_getInstance()
Возвращает 0, то ничего не получилось.

Re: Рутокен, ЭЦП и C#

Уффф. Всё, уже ничего не нужно я смог разобраться, и сделать через КриптоПРО .NET