(2019-10-11 11:49:38 отредактировано Евгений Рябцев)

Рутокен ЭЦП 2.0 и XCA

Пытаюсь использовать Рутокен ЭЦП 2.0 с программой XCA в качестве управляющего ключами под Windows 7/10. Что получается:
1. Драйверы rtDrivers.exe поставились, токен виден.
2. В программе XCA выбираю в меню Файл / Настройки на вкладке Провайдер PKCS#11 файл C:/Windows/System32/rtPKCS11ECP.dll, он отмечается зелёной галочкой.
3. Рутокен становится доступен в меню Модуль защиты программы XCA. Создаю сертификат, генерируя секретный ключ непосредственно на токене. На предложение сохранить на токене и сам сертификат отвечаю утвердительно.
4. В программе XCA сертификат и его ключ на Рутокене вижу.

https://forum.rutoken.ru/uploads/images/2019/10/629e0047d34855df8741ff688239782e.png

5. Захожу посмотреть на них в Панели управления Рутокен. Там их не видно.
6. При попытке импортировать сертификат из файла через Панель управления Рутокен оказалось, что файлы с расширением .crt не входят в список "всех файлов сертификатов" и, если выбраны через *.*, не воспринимаются с сообщением "Не удалось распознать тип файла. Выберите другой файл". В то же время, после переименования файла из .crt в .cer, он воспринялся нормально (формат файла - PEM).
7. Воспринятый сертификат, однако, не импортировался, с сообщением, что такой объект уже существует.

https://forum.rutoken.ru/uploads/images/2019/10/86ceb2dac0565aed112e2253b33ccfd5.png

8. Для проверки снова открыл XCA и удалил сертификат с Рутокена. Сертификат удалился и после этого успешно импортировался через Панель управления Рутокен, но показывает, что к нему нет секретного ключа.

https://forum.rutoken.ru/uploads/images/2019/10/6acbf8c68c0533acf1222f4f9484e5aa.png

9. Если теперь просмотреть содержимое Рутокена в программе XCA, видно, что сертификат на нём есть, хотя и с другим обозначением. В XCA его можно переименовать, что никак не сказывается на его отображении в Панели управления Рутокен и не способствует установления соответствия со всё ещё находящемся на Рутокене секретным ключом.

https://forum.rutoken.ru/uploads/images/2019/10/f0dea0fb76ac682ae2db608b46164d5a.png

10. Если генерировать ключ на компьютере и экспортировать / импортировать через файл .p12, оно вроде работает, но хотелось бы создавать ключ непосредственно на токене.

Re: Рутокен ЭЦП 2.0 и XCA

Здравствуйте.

Это нормально и тут не нужно ориентироваться на "Панель управления Рутокен", она не умеет отображать такой сертификат.
Можно доверять интерфейсу самого XCA, где ключ и сертификат отображаются, а можно еще убедиться в их наличии на нашем портале ra.rutoken.ru

(2019-10-11 14:23:57 отредактировано Евгений Рябцев)

Re: Рутокен ЭЦП 2.0 и XCA

Тогда другой вопрос. Сертификат, который я добавил на Рутокен через .p12, автоматически попал в хранилище сертификатов пользователя Windows (Сертификаты - текущий пользователь / Личное / Сертификаты), как я понимаю, через службу "Распространение сертификата". Сертификаты, которые я сохраняю через XCA, с секретными ключами создаваемыми на токене, в это хранилище не попадают. Сертификат к ключу, который я создал на ra.rutoken.ru, тоже не попал ни в список Панели управления Рутокен ни в хранилище сертификатов Windows.

Хотелось бы использовать сертификаты с размещёнными на Рутокен ключами как будто они установлены в Windows (без плагинов браузера и т.п.). Пока у меня это получается только с сертификатами, видимыми через Панель управления Рутокен (т.е. устанавливаемыми через .p12).

Ещё, пока я всё это тестировал, создал сертификат (.p12), который Панель управления Рутокен отказывается импортировать. Сначала говорит "Вставьте смарт-карту", потом, после отмены (Рутокен-то вставлен и видится, но кнопка ОК недоступна), "Ошибка импорта. Подробности: : 0x8010006e".

Re: Рутокен ЭЦП 2.0 и XCA

Евгений Рябцев пишет:

Хотелось бы использовать сертификаты с размещёнными на Рутокен ключами как будто они установлены в Windows (без плагинов браузера и т.п.). Пока у меня это получается только с сертификатами, видимыми через Панель управления Рутокен (т.е. устанавливаемыми через .p12).

Расскажите, пожалуйста, для чего планируете использовать такие самоподписные-сертификаты?
Почему не подходят такие, которые отображаются в панели управления рутокен?

Евгений Рябцев пишет:

Ещё, пока я всё это тестировал, создал сертификат (.p12), который Панель управления Рутокен отказывается импортировать. Сначала говорит "Вставьте смарт-карту", потом, после отмены (Рутокен-то вставлен и видится, но кнопка ОК недоступна), "Ошибка импорта. Подробности: : 0x8010006e".

Тут поподробнее опишите как именно создаете такой сертификат?

Re: Рутокен ЭЦП 2.0 и XCA

Такие, которые отображаются в панели управления рутокен, как раз подходят. Есть задумка использовать токены для аутентификации пользователей КИИ, вместо паролей. Не обязательно самоподписанные, это не принципиально. При этом выбираться сертификат будет из списка, предоставляемого чем-то вроде нижеследующего кода C# или браузером при затребовании в соединении TLS клиентского сертификата. И туда и туда попадают сертификаты, доступные Windows. Пока у меня наблюдается однозначное соответствие между сертификатами, доступными Windows и сертификатами, видимыми в панели управления рутокен.

X509Store store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates;

К сожалению не помню как именно я создал не импортирующийся в токен сертификат. Сам сертификат прилагаю, пароль к нему 1. Для проверки импортировал его в XCA (всё норм) и экспортировал заново - ситуация та же.

https://www.dropbox.com/s/uy0od26sp28c4 … 4.p12?dl=0

Re: Рутокен ЭЦП 2.0 и XCA

Евгений Рябцев пишет:

Такие, которые отображаются в панели управления рутокен, как раз подходят. Есть задумка использовать токены для аутентификации пользователей КИИ, вместо паролей. Не обязательно самоподписанные, это не принципиально. При этом выбираться сертификат будет из списка, предоставляемого чем-то вроде нижеследующего кода C# или браузером при затребовании в соединении TLS клиентского сертификата. И туда и туда попадают сертификаты, доступные Windows. Пока у меня наблюдается однозначное соответствие между сертификатами, доступными Windows и сертификатами, видимыми в панели управления рутокен.

Честно говоря не совсем понял можно ли считать этот вопрос для вас решенным? Или нужно что-то большее, чем сертификаты, отображаемые в панели управления рутокен?

Евгений Рябцев пишет:

К сожалению не помню как именно я создал не импортирующийся в токен сертификат. Сам сертификат прилагаю, пароль к нему 1. Для проверки импортировал его в XCA (всё норм) и экспортировал заново - ситуация та же.

https://www.dropbox.com/s/uy0od26sp28c4 … 4.p12?dl=0

Проверил импорт этого файла у себя и проблем не обнаружил, файл импортировался без ошибок — скриншот

Re: Рутокен ЭЦП 2.0 и XCA

Пока получилось сделать отображаемыми в панели управления рутокен только сертификаты с секретным ключом, генерируемым вне рутокена. Для полного счастья хотелось бы добиться того же с секретным ключом, генерируемым непосредственно на токене.

По импорту - странно. У меня воспроизводится на обоих токенах. Может быть гляну поподробнее, ну да и бог бы с ним.

Re: Рутокен ЭЦП 2.0 и XCA

Евгений Рябцев пишет:

Есть задумка использовать токены для аутентификации пользователей КИИ, вместо паролей.

А как в рабочем варианте планировали выпускать сертификаты пользователей? Например, развернуть Microsoft CA или как?
XCA через PKCS#11 делает RSA ключи и именно они не отображаются в панели управления.

Как вариант можно выпускать через наш минидрайвер и тогда сертификаты будут видны ( вот статья для примера — https://habr.com/ru/company/aktiv-company/blog/327232/ ).
Если же даже на https://ra.rutoken.ru сгенерировать ГОСТ-ключи и сертификат к ним, то в панели управления они появятся.

Re: Рутокен ЭЦП 2.0 и XCA

Боевой CA планировали отдать на откуп заказчику (мы изготовитель), но рекомендовать какой-то вариант как его сделать. Соответственно сам заказчик доверяет своему CA, доверие третьих лиц не требуется. Мы бы с изделием поставляли заводские номерные токены для первоначальной настройки, с однозначным соответствием между токеном и экземпляром изделия (сертификат токена ставится на изделие).

Попробовал создавать ключи через Windows Crypto API (CryptAcquireContext/CryptGenKey), ключи видны нормально. Благодарю за поддержку, по этому пункту больше помощь не требуется.

Ещё такой вопрос: можно ли как-нибудь перераспределить полномочия между пользователем и администратором токена? Например, чтобы пользователь не мог удалить ключ/сертификат?

Re: Рутокен ЭЦП 2.0 и XCA

Евгений Рябцев пишет:

Ещё такой вопрос: можно ли как-нибудь перераспределить полномочия между пользователем и администратором токена? Например, чтобы пользователь не мог удалить ключ/сертификат?

Именно через утилиту "Панель управления Рутокен" удалить сертификат можно только зная PIN-код администратора, поэтому, например, для системного администратора компании заказчика есть смысл менять стандартный PIN перед тем как отдать рутокен на руки пользователю. ВАЖНО — не потерять и не забыть новый PIN администратора, т.е. нужно вести учет токенов.

Re: Рутокен ЭЦП 2.0 и XCA

Хм. У меня по-другому. Спрашивает пин-код пользователя и, при его вводе, сертификат успешно удаляется.

https://forum.rutoken.ru/uploads/images/2019/10/047839250185328d60e21ef121d26fc2.png
https://forum.rutoken.ru/uploads/images/2019/10/fd13b21c9476bff2a0db588ca8266b0d.png

Re: Рутокен ЭЦП 2.0 и XCA

Потому что этот сертификат с ключами был импортирован на токен.
Если делать неизвлекаемые ключи на токене, то надо PIN администратора.

Re: Рутокен ЭЦП 2.0 и XCA

Хм. Проверил. Создаю ключевую пару на токене средствами Windows Crypto API (токен какое-то время мигает, генерирует). Пробую удалить через панель управления рутокен - запрашивает пин пользователя, удаляет. Создаю ещё одну ключевую пару. Создаю к ней в XCA сертификат, через панель управления рутокен назначаю сертификат ключевой паре, сертификат назначается. Выхожу из панели управления, перевтыкаю токен, пробую удалить - запрашивает пин пользователя, удаляет. Что я делаю не так?

https://forum.rutoken.ru/uploads/images/2019/10/5cbd1dcd8f2d7222dd7a2ac1b44a93c4.png

Для сравнения, как это выглядит в XCA. Видно различие между созданными и импортированными сертификатами (_S или _E на конце названия контейнера). XCA ведёт себя одинаково с импортированными и созданными ключами, отказываясь удалять что те, что другие (ну и бог бы с ней).

https://forum.rutoken.ru/uploads/images/2019/10/7dd838e540dbedb2754601679bbbc094.png

Re: Рутокен ЭЦП 2.0 и XCA

Евгений Рябцев пишет:

Хм. Проверил. Создаю ключевую пару на токене средствами Windows Crypto API (токен какое-то время мигает, генерирует). Пробую удалить через панель управления рутокен - запрашивает пин пользователя, удаляет. Создаю ещё одну ключевую пару. Создаю к ней в XCA сертификат, через панель управления рутокен назначаю сертификат ключевой паре, сертификат назначается. Выхожу из панели управления, перевтыкаю токен, пробую удалить - запрашивает пин пользователя, удаляет. Что я делаю не так?

Тогда опишите подробнее этот процесс генерации.

Re: Рутокен ЭЦП 2.0 и XCA

Вот как-то так:

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern bool CryptAcquireContext(out IntPtr hProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        static extern bool CryptReleaseContext(IntPtr hProv, Int32 dwFlags);

        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern bool CryptGetProvParam(IntPtr hProv, uint dwParam, [MarshalAs(UnmanagedType.LPStr)] StringBuilder pbData, ref uint dwDataLen, uint dwFlags);

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern bool CryptGenKey(IntPtr hProv, uint Algid, uint dwFlags, out IntPtr phKey);

        const uint AT_SIGNATURE = 2;
        const uint CRYPT_FIRST = 1;
        const uint CRYPT_NEXT = 2;
        const uint CRYPT_NEWKEYSET = 8;
        const uint CRYPT_SILENT = 64;
        const uint PP_ENUMCONTAINERS = 2;
        const uint PROV_RSA_FULL = 1;

        const uint KEY_SIZE_1024 = 1024 << 16;
        const uint KEY_SIZE_2048 = 2048 << 16;

        const string ProviderName = "Microsoft Base Smart Card Crypto Provider";

        private void btnCreatePrivateKey_Click(object sender, EventArgs e)
        {
            if (lstCerts.Items.Contains(txtContainer.Text)) {
                MessageBox.Show(String.Format("Контейнер ключей с именем '{0}' уже существует. Повторное использование контейнера для создания нового ключа не допускается. Выберите другое имя для контейнера.", txtContainer.Text), "Контейнер уже существует", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            IntPtr provider;
            if (!CryptAcquireContext(out provider, txtContainer.Text, ProviderName, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
                MessageBox.Show(String.Format("Не удалось создать контейнер ключей '{0}', код ошибки {1}. Убедитесь, что токен доступен.", txtContainer.Text, Marshal.GetLastWin32Error()), "Операция неуспешна", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            IntPtr key;
            if (CryptGenKey(provider, AT_SIGNATURE, KEY_SIZE_2048, out key)) {
                RefreshContainers();
                MessageBox.Show("Новый ключ успешно создан. Используйте центр сертификации для создания сертификата к этому ключу. Используйте панель управления токенами для импорта сертификата на токен.", "Ключ создан", MessageBoxButtons.OK, MessageBoxIcon.Information);
            } else {
                MessageBox.Show(String.Format("Не удалось создать новый ключ. Код ошибки {0}.", Marshal.GetLastWin32Error()), "Операция неуспешна", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            CryptReleaseContext(provider, 0);
        }