Почему CryptAcquireContext возвращает ERROR_ACCESS_DENIED при вызове из процесса, запущенного через WMI?

У меня есть исполняемый файл, который вызывает CryptAcquireContext с CRYPT_NEWKEYSET:

BOOL b_result;
HCRYPTPROV prov;

b_result = CryptAcquireContext(&prov, L"testcontext6", MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET);

if(!b_result) {
    int err = GetLastError();
    fprintf(stderr, "Error acquiring context: %#x\n", err);
    return 1;
}
return 0;

Если я запускаю это локально, все работает нормально. Если я запускаю его через WMI следующим образом, он возвращает ошибку 0x5 (ERROR_ACCESS_DENIED):

using (var processClass = new ManagementClass(m_scope, new ManagementPath("Win32_Process"), new ObjectGetOptions()))
{
    var inParams = processClass.GetMethodParameters("Create");
    inParams["commandLine"] = @"cmd.exe /c C:\CppTest.exe 2>C:\test.log";
    var outParams = processClass.InvokeMethod("Create", inParams, null);
    return outParams["ProcessId"];
}

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


person richvdh    schedule 21.12.2012    source источник
comment
Это локальный WMI или вы пытаетесь запустить удаленный процесс через WMI?   -  person Remus Rusanu    schedule 21.12.2012
comment
Я запускаю удаленный процесс.   -  person richvdh    schedule 21.12.2012
comment
Происходит ли делегирование? («два прыжка»)   -  person Remus Rusanu    schedule 21.12.2012
comment
Нет, задействованы только два компьютера.   -  person richvdh    schedule 21.12.2012
comment
Вам нужно будет прочитать статью MSDN для метода Create(). Обратите внимание на использование impersonationLevel в примере кода. И явное предупреждение о том, что запуск интерактивных процессов на целевой машине не разрешен. Cmd.exe — это интерактивный процесс. Попробуйте поработать с утилитой PsExec от SysInternals.   -  person Hans Passant    schedule 21.12.2012
comment
@HansPassant: спасибо. У меня уже есть impersonationLevel=Impersonate; и у меня возникает та же проблема, когда я запускаю тестовую программу без cmd.exe - я просто делал это для простоты перенаправления ошибки в файл. И да, это прекрасно работает с PsExec. Я предполагаю, что проблема в том, что CRYPT_NEWKEYSET требует интерактивного входа в систему.   -  person richvdh    schedule 21.12.2012
comment
Это фактически не работает для Process.Start в C#, если UseShellExecute не используется. Вы нашли обходной путь?   -  person halivingston    schedule 21.03.2013


Ответы (1)


Среда под Win32_Process.CreateProcess запрещает использование интерактивных операций. и оказывается, что использование CryptAcquireContext для доступа к контейнерам ключей, специфичным для пользователя (а не для всей машины), не работает в неинтерактивных средах (см. http://social.msdn.microsoft.com/Forums)./uk/clr/thread/2033c171-0809-4e14-aa50-1b9287389cb3, например).

person richvdh    schedule 27.12.2012