NCryptOpenStorageProvider + KeyIso

Перезапуск службы после открытия провайдера разрывает соединение и заставляет перезапускать все приложение.

Шаг за шагом:

  1. Откройте провайдера NCryptOpenStorageProvider(myProvider, MS_KEY_STORAGE_PROVIDER, 0) — будет «00000000» (ERROR_SUCCESS)

  2. Перезапустите службу CNG Key Isolation.

  3. Снова откройте провайдера NCryptOpenStorageProvider(myProvider, MS_KEY_STORAGE_PROVIDER, 0) — будет «80070006» (ERROR_INVALID_HANDLE)

Как правильно открыть провайдер после перезапуска службы без перезапуска приложения?

Ошибка ERROR_INVALID_HANDLE связана с недопустимым дескриптором привязки RPC между NCrypt (BCrypt) и службой. Я не думаю, что существует задокументированный способ сброса этого дескриптора привязки RPC, он статически кэшируется dll в памяти вашего процесса, это также может быть сделано специально, чтобы избежать некоторых проблем с безопасностью.

Simon Mourier 24.08.2024 15:50

Я это понимаю. Чего я не понимаю, так это как остальной софт выдерживает перезапуск этого сервиса и не требует последующего перезапуска? Как мне научить свое приложение тоже не умирать, а автоматически переподключаться к провайдеру после перезапуска сервиса?

kazuser 24.08.2024 19:14

действительно, когда NCryptOpenStorageProvider с MS_KEY_STORAGE_PROVIDER вызывается в первый раз, MsProvCryptOpenProvider_KeyIso вызывается из ncryptprov.dll и внутри этой функции KeyIsoServerBind вызывается. при следующих вызовах MsProvCryptOpenProvider_KeyIso также вызывался, но KeyIsoServerBind вызывался только один раз в первый раз, и это дескриптор кеша. для uncache нужен KeyIsoServerUnbind, но, судя по моему быстрому взгляду, он звонил только из MSProvModuleUninit < UninitializeCNGProv, который вызывал ncryptprov.dll выгружался. и похоже, что нет возможности выгрузить эту dll после ее загрузки в качестве провайдера.

RbMm 24.08.2024 22:45

и не только ваше приложение, если оно затронуто. системные службы тоже. после перезапуска службы keyiso я больше не могу разблокировать / войти в Windows с помощью PIN-кода. у меня возникла ошибка, что-то пошло не так, ваш пин-код недоступен (код 0x80070006..)

RbMm 24.08.2024 22:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

когда ты впервые звонишь

NCryptOpenStorageProvider(&hProvider, MS_KEY_STORAGE_PROVIDER, 0);

ncryptprov.dll загружается, и когда его функция MsProvCryptOpenProvider_KeyIso вызывается (это NCryptOpenStorageProviderFn из NCRYPT_KEY_STORAGE_FUNCTION_TABLE) в первый раз (MsProvCryptOpenProvider_KeyIso вызывается каждый раз, когда вы открываете MS_KEY_STORAGE_PROVIDER), он вызывает KeyIsoServerBind и кэширует некоторый дескриптор службы KeyIso. который, конечно, стал недействительным после перезапуска службы. насколько я понимаю, KeyIsoServerUnbind (внутренняя функция в ncryptprov.dll) вызывается только тогда, когда ncryptprov.dll выгружается. и сам ncrypt никогда не выгружает уже загруженных провайдеров, даже после того, как все дескрипторы к нему были закрыты (через NCryptFreeObject). так что на самом деле это невозможно исправить без перезапуска процесса.

однако я отмечаю, что некоторые встроенные компоненты Windows также повлияли. когда я блокирую рабочую станцию, а затем пытаюсь разблокировать ее снова с помощью поставщика PIN-кода, я получаю следующую ошибку

Спасибо большое 👍 Даже не верится... Я (вы, мы, они) можем написать простую утилиту, которая будет просто перезапускать этот сервис раз в минуту — и заставлять пользователей по всему миру постоянно перезагружать свои системы? Приятно 🥲

kazuser 25.08.2024 07:28

@kazuser можно написать и утилиту, которая будет крашить систему. и что? смысл ? в случае входа в систему с помощью PIN-кода LogonUI — ngccredprovider вызывает службу NgcSvc (отображаемое имя «Microsoft Passport»). и эта служба выполняет еще один удаленный вызов к NgcCtnrSvc («Контейнер паспорта Microsoft»), и здесь уже ncryptprov.dll выполняет третий удаленный вызов службы KeyIso («Изоляция ключей CNG»), который не выполняет кэшированный дескриптор. однако после перезапуска вход в систему по PIN-коду NgcCtnrSvc снова работает нормально

RbMm 25.08.2024 09:00

Другие вопросы по теме