DPAPI NG — NCryptProtectSecret возвращает NTE_ENCRYPTION_FAILURE

#windows-server-2012-r2 #dpapi #cng

#windows-server-2012-r2 #dpapi #cng

Вопрос:

Я пытаюсь зашифровать данные с помощью DPAPI-NG, но это не удается при выполнении NCryptProtectSecret, он возвращает:

0x80090034 (NTE_ENCRYPTION_FAILURE)

Я создал NCryptCreateProtectionDescriptor с идентификатором локального пользователя SID:

 "SID=S-1-5-21-2942599413-360359348-3087651068-500"
  

Затем я использую этот экземпляр дескриптора в качестве входных данных для NCryptProtectSecret, но это не работает.

Если я использую дескриптор защиты от:

 "LOCAL=user"
  

кажется, все в порядке, но это не работает с SID для пользователя или группы. Я тестировал это на Windows Server 2012R2 и Windows Server 2016.

Есть идеи?

Вот пример кода:

 SECURITY_STATUS Status;
PBYTE       ProtectedData = NULL;
ULONG       ProtectedDataLength = 0;
NCRYPT_DESCRIPTOR_HANDLE    DescriptorHandle = NULL;
LPCWSTR ProtectionDescString = L"SID=S-1-5-21-2942599413-360359348-3087651068-500";

Status = NCryptCreateProtectionDescriptor(
                                        ProtectionDescString,
                                        0,
                                        amp;DescriptorHandle
                                        );      
// Status is ERROR_SUCCESS (zero)


LPCWSTR SecretString = L"Some message to protect";
PBYTE Secret = (PBYTE)SecretString;
DWORD SecretLength = (ULONG)( (wcslen(SecretString) 1)*sizeof(WCHAR) );

Status = NCryptProtectSecret(
                        DescriptorHandle,
                        0,
                        PlainText,
                        PlainTextLength,
                        NULL, // Use default allocations by LocalAlloc/LocalFree
                        NULL, // Use default parent windows handle.
                        amp;ProtectedData,  // out LocalFree
                        amp;ProtectedDataLength
                        );

**// Status == NTE_ENCRYPTION_FAILURE**
  

Ответ №1:

Я столкнулся с этой проблемой и обнаружил, что причиной была работа нашего домена на функциональном уровне, который был ниже 2012. После обновления домена до 2012 проблема была решена.

Быстрым и простым способом определения функционального уровня является следующий командлет PowerShell

 [system.directoryservices.activedirectory.Forest]::GetCurrentForest().ForestMode
  

Комментарии:

1. У меня больше нет системы с проблемой 🙂 Но поскольку в то время это, возможно, было проблемой, я отмечу это как ответ. Это может быть более полезным, чем мой. Спасибо, что поделились этим.

2. Я могу шифровать с использованием SID домена; и наш контроллер домена Windows Server 2012 работает в фоновом режиме в Windows2003Forest

Ответ №2:

Замените открытый текст и длину открытого текста на Secret и SecretLength.

Комментарии:

1. Привет, Микша. Это была ошибка при копировании ранее. Это секрет и SecretLength, как вы сказали.

Ответ №3:

Я не понял, в чем была проблема, но в другом домене все работало нормально. Microsoft также подтвердила, что рабочий пример, который мы им отправили, был правильным, но они не объяснили, в чем проблема.

Ответ №4:

Убедитесь, что пользователь, запускающий приложение, действительно является пользователем

 S-1-5-21-2942599413-360359348-3087651068-500
  

Вы можете проверить это из командной строки и:

 >whoami /user

USER INFORMATION
----------------

User Name     SID
============= ============================================
erbiumzeljko S-1-5-21-2942599413-360359348-3087651068-500
  

Я получил, NTE_ENCRYPTION_FAILURE когда я пытался использовать SID группы, которого у меня на самом деле не было ( Domain Users группа).

Возможно, у вас просто неверный sid по сравнению с тем, кто запускает код.