logo Наши способы организации безопасного удалённого доступа к рабочим местам и корпоративным ресурсам
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline itmindco  
#1 Оставлено : 3 марта 2020 г. 10:09:12(UTC)
itmindco

Статус: Новичок

Группы: Участники
Зарегистрирован: 03.03.2020(UTC)
Сообщений: 3
Российская Федерация
Откуда: Хабаровск

Здравствуйте.
Импортирую pfx в silent режиме с закрытым ключом. Сертификат устанавливается и в дальнейшем при использовании не требует пароля (можно экспортировать сертификат с закрытым ключом обратно в pfx уже без пароля). Как задать (оставить тем же) пароль?
Пробовал через CryptSetProvParam, но не нашел как получить HCRYPTPROV для конкретного контейнера (сертификата)

код импорта:
Код:

        void Import()
        {
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadWrite);

            var certs = Read(@"c:\temp\cert\test2.pfx", "123");
            foreach(var cert in certs)
            {
                store.Add(cert);
            }

            store.Close();
        }

        public X509Certificate2[] Read(string filename, string password)
        {

            FileStream stream = new FileStream(filename, FileMode.Open);
            byte[] buffer = new byte[stream.Length];
            stream.Read(buffer, 0, buffer.Length);
            stream.Close();

            CRYPT_DATA_BLOB cryptdata = new CRYPT_DATA_BLOB();
            cryptdata.cbData = buffer.Length;
            cryptdata.pbData = Marshal.AllocHGlobal(cryptdata.cbData);
            Marshal.Copy(buffer, 0, cryptdata.pbData, buffer.Length);

            IntPtr hMemStore = PFXImportCertStore(ref cryptdata, password, PKCS12_IMPORT_SILENT);
            Marshal.FreeHGlobal(cryptdata.pbData);

            uint provinfosize = 0;
            uint hcryptrovsize = 0;

            List<X509Certificate2> certs = new List<X509Certificate2>();

            IntPtr certHandle = IntPtr.Zero;
            while ((certHandle = CertEnumCertificatesInStore(hMemStore, certHandle)) != IntPtr.Zero)
            {
                
                if (CertGetCertificateContextProperty(certHandle, CERT_KEY_PROV_INFO_PROP_ID, IntPtr.Zero, ref provinfosize))
                {
                    IntPtr info = Marshal.AllocHGlobal((int)provinfosize);
                    if (CertGetCertificateContextProperty(certHandle, CERT_KEY_PROV_INFO_PROP_ID, info, ref provinfosize))
                    {
                        IntPtr HCRYPTPROV = IntPtr.Zero;
                        if (CertGetCertificateContextProperty(certHandle, CERT_HCRYPTPROV_OR_NCRYPT_KEY_HANDLE_PROP_ID, HCRYPTPROV, ref hcryptrovsize))
                        {
                            CryptSetProvParam(HCRYPTPROV, PP_SET_PIN, Encoding.ASCII.GetBytes("123"), 0); // в эту строчку не заходит
                        }
                        else
                        {
                            var err = GetLastError(); //ошибка CRYPT_E_NOT_FOUND
                        }

                        
                        var certData = new X509Certificate2(certHandle).Export(X509ContentType.SerializedCert);
                        certs.Add(new X509Certificate2(certData));
                    }
                    Marshal.FreeHGlobal(info);

                }
            }

            Marshal.FreeHGlobal(hMemStore);
            return certs.ToArray();

        }


так же без пароля получается после такой консольной команды:
certmgr.exe -inst -pfx -pin 123 -silent -file c:\temp\cert\test.pfx

Отредактировано пользователем 3 марта 2020 г. 10:10:09(UTC)  | Причина: Не указана

Offline Максим Коллегин  
#2 Оставлено : 3 марта 2020 г. 17:35:40(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 5,887
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 17 раз
Поблагодарили: 578 раз в 519 постах
Нужно открыть провайдер у сертификата и установить пин-код.
X509Certificate.PrivateKey
Gost3410CryptoServiceProvider.SetContainerPassword

Отредактировано пользователем 3 марта 2020 г. 17:38:06(UTC)  | Причина: Не указана

Знания в базе знаний, поддержка в техподдержке
Offline itmindco  
#3 Оставлено : 4 марта 2020 г. 1:53:32(UTC)
itmindco

Статус: Новичок

Группы: Участники
Зарегистрирован: 03.03.2020(UTC)
Сообщений: 3
Российская Федерация
Откуда: Хабаровск

Не сработало, все равно в хранилище сертификат без пароля
Код:

        void Import()
        {
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadWrite);

            var certs = Read(@"c:\temp\cert\test.pfx", "123");
            SecureString pass = new SecureString();
            pass.AppendChar('1');
            pass.AppendChar('2');
            pass.AppendChar('3');
            foreach (var cert in certs)
            {
                ((Gost3410_2012_256CryptoServiceProvider)cert.PrivateKey).SetContainerPassword(pass);
                store.Add(cert);
            }


            store.Close();
       }

Отредактировано пользователем 4 марта 2020 г. 1:54:10(UTC)  | Причина: Не указана

Offline Максим Коллегин  
#4 Оставлено : 4 марта 2020 г. 8:21:30(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 5,887
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 17 раз
Поблагодарили: 578 раз в 519 постах
Какая версия CSP?

Отредактировано пользователем 4 марта 2020 г. 8:47:13(UTC)  | Причина: Не указана

Знания в базе знаний, поддержка в техподдержке
Offline itmindco  
#5 Оставлено : 4 марта 2020 г. 8:24:44(UTC)
itmindco

Статус: Новичок

Группы: Участники
Зарегистрирован: 03.03.2020(UTC)
Сообщений: 3
Российская Федерация
Откуда: Хабаровск

Автор: Максим Коллегин Перейти к цитате
Какая версия CSP?

4.0
Offline Максим Коллегин  
#6 Оставлено : 4 марта 2020 г. 8:46:42(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 5,887
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 17 раз
Поблагодарили: 578 раз в 519 постах
Прошу прощения, ввёл в заблуждение.
Эта функция предъявляет пароль.
Единственный способ установить пароль — вызывать через interop CryptSetProvParam ( PP_SET_PIN )
Знания в базе знаний, поддержка в техподдержке
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.