Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8029665
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T00:30:00+00:00 2026-06-05T00:30:00+00:00

I am trying to decrypt WEP profile’s key using CryptUnprotectData . The way I

  • 0

I am trying to decrypt WEP profile’s key using CryptUnprotectData. The way I fetched the profile key is by exporting the profile using netsh.

netsh wlan export profile name="MyWEP" folder="./"

For now, I manually copied the key material from the .xml file generated by the netsh command to my program. And the way, I am decrypting is –

DATA_BLOB DataOut, DataVerify;
DataOut.cbData = encryptData.length();
DataOut.pbData = (BYTE*)("I_Manually_Copy_The_WEP_Key_Here");

if (CryptUnprotectData( &DataOut,
                        NULL,
                        NULL,
                        NULL,
                        NULL,
                        0,
                        &DataVerify))
{
    printf("The decrypted data is: %s\n", DataVerify.pbData);
}
else
{
    printf("Failed. Error Code: %d", GetLastError());
}

But I am getting the error code 13 citing Invalid Data. What am I doing wrong ? On Win 7 and later, I can directly use WlanGetProfile with the parameter WLAN_PROFILE_GET_PLAINTEXT_KEY . But I have NO option on Vista than to use the CryptUnprotectData function. I have seen similar posts here, here but didn’t get much useful information. Also, I am using the same system with same user log on credentials. Could any one please suggest me how to proceed ?

PS: I have posted the same question on Windows Desktop SDK forums, but haven’t got response yet. Trying my luck on SO.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-05T00:30:02+00:00Added an answer on June 5, 2026 at 12:30 am

    I like questions about Windows Security. So if I occasionally see such one I try to solve it.

    In your case you did already the first step by the usage of netsh.exe wlan export profile ... to export the data from the WLAN profile in XML file. The file contains <keyMaterial> element. The data inside of the element are binary data encoded as the Hex: (something like 01000000D08C9DDF0115D1118C7A00C0...).

    So what you need to do first of all is to decode the string to binary data. You can use CryptStringToBinary with CRYPT_STRING_HEX parameter to decode the string to binary.

    The next step will be to fill DATA_BLOB with the binary data and call CryptUnprotectData to get the result, but… There are small problem. How you can read in the documentation of WlanGetProfile the following

    By default, the keyMaterial element returned in the profile pointed to
    by the pstrProfileXml is encrypted. If your process runs in the
    context of the LocalSystem account on the same computer, then you can
    unencrypt key material by calling the CryptUnprotectData function.

    Windows Server 2008 and Windows Vista: The keyMaterial element
    returned in the profile schema pointed to by the pstrProfileXml is
    always encrypted. If your process runs in the context of the
    LocalSystem account, then you can unencrypt key material by calling
    the CryptUnprotectData function.

    So to be able to unencrypt the key we have to call CryptUnprotectData in LocalSystem security context. If your program already run under LocalSystem context you can do this directly. If it’s not so, but you have administrative rights or you have at least Debug privilege, you can “to borrow” the LocalSystem token from some other process running on the computer. For example one can get the process token of “winlogon.exe” process and impersonate it.

    The following demo program enumerate processes using NtQuerySystemInformation method (see my old answer) which I personally prefer. One can use EnumProcesses or other well-known ways to do the same. Here is the code which worked at me

    #include <Windows.h>
    #include <tchar.h>
    #include <stdio.h>
    #pragma comment (lib, "Crypt32.lib")
    
    #define STATUS_SUCCESS               ((NTSTATUS)0x00000000L)
    #define STATUS_INFO_LENGTH_MISMATCH  ((NTSTATUS)0xC0000004L)
    
    typedef enum _SYSTEM_INFORMATION_CLASS {
        SystemProcessInformation = 5
    } SYSTEM_INFORMATION_CLASS;
    
    typedef struct _UNICODE_STRING {
        USHORT Length;
        USHORT MaximumLength;
        PWSTR  Buffer;
    } UNICODE_STRING;
    
    typedef LONG KPRIORITY; // Thread priority
    
    typedef struct _SYSTEM_PROCESS_INFORMATION_DETAILD {
        ULONG NextEntryOffset;
        ULONG NumberOfThreads;
        LARGE_INTEGER SpareLi1;
        LARGE_INTEGER SpareLi2;
        LARGE_INTEGER SpareLi3;
        LARGE_INTEGER CreateTime;
        LARGE_INTEGER UserTime;
        LARGE_INTEGER KernelTime;
        UNICODE_STRING ImageName;
        KPRIORITY BasePriority;
        HANDLE UniqueProcessId;
        ULONG InheritedFromUniqueProcessId;
        ULONG HandleCount;
        BYTE Reserved4[4];
        PVOID Reserved5[11];
        SIZE_T PeakPagefileUsage;
        SIZE_T PrivatePageCount;
        LARGE_INTEGER Reserved6[6];
    } SYSTEM_PROCESS_INFORMATION_DETAILD, *PSYSTEM_PROCESS_INFORMATION_DETAILD;
    
    typedef NTSTATUS (WINAPI *PFN_NT_QUERY_SYSTEM_INFORMATION)(
      IN       SYSTEM_INFORMATION_CLASS SystemInformationClass,
      IN OUT   PVOID SystemInformation,
      IN       ULONG SystemInformationLength,
      OUT OPTIONAL  PULONG ReturnLength
    );
    
    //
    // The function changes a privilege named pszPrivilege for
    // the current process. If bEnablePrivilege is FALSE, the privilege
    // will be disabled, otherwise it will be enabled.
    //
    BOOL SetCurrentPrivilege (LPCTSTR pszPrivilege,   // Privilege to enable/disable
                              BOOL bEnablePrivilege)  // to enable or disable privilege
    {
        HANDLE hToken;
        TOKEN_PRIVILEGES tp;
        LUID luid;
        TOKEN_PRIVILEGES tpPrevious;
        DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
        BOOL bSuccess = FALSE;
    
        if (!LookupPrivilegeValue(NULL, pszPrivilege, &luid)) return FALSE;
    
        if (!OpenProcessToken (GetCurrentProcess(),
                               TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
                               &hToken
                              )) return FALSE;
    
        //
        // first pass.  get current privilege setting
        //
        tp.PrivilegeCount           = 1;
        tp.Privileges[0].Luid       = luid;
        tp.Privileges[0].Attributes = 0;
    
        AdjustTokenPrivileges(
                hToken,
                FALSE,
                &tp,
                sizeof(TOKEN_PRIVILEGES),
                &tpPrevious,
                &cbPrevious);
    
        if (GetLastError() == ERROR_SUCCESS) {
            //
            // second pass.  set privilege based on previous setting
            //
            tpPrevious.PrivilegeCount     = 1;
            tpPrevious.Privileges[0].Luid = luid;
    
            if(bEnablePrivilege)
                tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
            else
                tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
                    tpPrevious.Privileges[0].Attributes);
    
            AdjustTokenPrivileges(
                    hToken,
                    FALSE,
                    &tpPrevious,
                    cbPrevious,
                    NULL,
                    NULL);
    
            if (GetLastError() == ERROR_SUCCESS) bSuccess=TRUE;
    
            CloseHandle(hToken);
        }
        else {
            DWORD dwErrorCode = GetLastError();
    
            CloseHandle(hToken);
            SetLastError(dwErrorCode);
        }
    
        return bSuccess;
    }
    
    DWORD GetProcessIdByProcessName (LPCWSTR pszProcessName)
    {
        SIZE_T bufferSize = 1024*sizeof(SYSTEM_PROCESS_INFORMATION_DETAILD);
        PSYSTEM_PROCESS_INFORMATION_DETAILD pspid = NULL;
        HANDLE hHeap = GetProcessHeap();
        PBYTE pBuffer = NULL;
        ULONG ReturnLength;
        PFN_NT_QUERY_SYSTEM_INFORMATION pfnNtQuerySystemInformation = (PFN_NT_QUERY_SYSTEM_INFORMATION)
            GetProcAddress (GetModuleHandle(TEXT("ntdll.dll")), "NtQuerySystemInformation");
        NTSTATUS status;
        int uLen = lstrlenW(pszProcessName)*sizeof(WCHAR);
    
        __try {
            pBuffer = (PBYTE) HeapAlloc (hHeap, 0, bufferSize);
    #pragma warning(disable: 4127)
            while (TRUE) {
    #pragma warning(default: 4127)
                status = pfnNtQuerySystemInformation (SystemProcessInformation, (PVOID)pBuffer,
                                                      bufferSize, &ReturnLength);
                if (status == STATUS_SUCCESS)
                    break;
                else if (status != STATUS_INFO_LENGTH_MISMATCH) { // 0xC0000004L
                    _tprintf (TEXT("ERROR 0x%X\n"), status);
                    return 1;   // error
                }
    
                bufferSize *= 2;
                pBuffer = (PBYTE) HeapReAlloc (hHeap, 0, (PVOID)pBuffer, bufferSize);
            }
    
            for (pspid = (PSYSTEM_PROCESS_INFORMATION_DETAILD)pBuffer; ;
                 pspid = (PSYSTEM_PROCESS_INFORMATION_DETAILD)(pspid->NextEntryOffset + (PBYTE)pspid)) {
    
                if (pspid->ImageName.Length == uLen && lstrcmpiW(pspid->ImageName.Buffer, pszProcessName) == 0)
                    return (DWORD)pspid->UniqueProcessId;
    
                if (pspid->NextEntryOffset == 0) break;
            }
        }
        __finally {
            pBuffer = (PBYTE) HeapFree (hHeap, 0, pBuffer);
        }
        return 0;
    }
    
    int _tmain()
    {
        BOOL bIsSuccess, bImpersonated = FALSE;
        HANDLE hProcess = NULL, hProcessToken = NULL;
        DATA_BLOB DataOut, DataVerify;
        // !!! in the next line you should copy the string from <keyMaterial>
        WCHAR szKey[] = L"01000000D08C9DDF0115D1118C7....";
        BYTE byKey[1024];
        DWORD cbBinary, dwFlags, dwSkip;
        DWORD dwProcessId = GetProcessIdByProcessName(L"winlogon.exe");
        if (dwProcessId == 0) return 1;
    
        bIsSuccess = SetCurrentPrivilege(SE_DEBUG_NAME, TRUE);
        if (!bIsSuccess) return GetLastError();
    
        __try {
            hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwProcessId);
            if (!hProcess) __leave;
            bIsSuccess = OpenProcessToken (hProcess, MAXIMUM_ALLOWED, &hProcessToken);
            if (!bIsSuccess) __leave;
            bIsSuccess = ImpersonateLoggedOnUser(hProcessToken);
            if (!bIsSuccess) __leave;
            bImpersonated = TRUE;
    
            cbBinary = sizeof(byKey);
            bIsSuccess = CryptStringToBinary (szKey, lstrlenW(szKey), CRYPT_STRING_HEX, // CRYPT_STRING_HEX_ANY
                byKey, &cbBinary, &dwSkip, &dwFlags);
            if (!bIsSuccess) __leave;
            DataOut.cbData = cbBinary;
            DataOut.pbData = (BYTE*)byKey;
    
            if (CryptUnprotectData (&DataOut, NULL, NULL, NULL, NULL, 0, &DataVerify)) {
                _tprintf(TEXT("The decrypted data is: %hs\n"), DataVerify.pbData);
            }
        }
        __finally {
            if (bImpersonated)
                RevertToSelf();
            if (hProcess)
                CloseHandle(hProcess);
            if (hProcessToken)
                CloseHandle(hProcessToken);
        }
    
        return 0;
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Am trying to decrypt a key encrypted by Java Triple DES function using PHP
I am trying to decrypt data that is encrypted using the Bouncy Castle library
I am trying to encrypt a string using C# and decrypt it using Python.
I'm trying to decrypt a string using mcrypt_decrypt, but I'm not sure how to
I'm trying to encrypt and decrypt data using RSA in C#. I have the
I am trying to decrypt using gpg.exe --passphrase-file my.passphrase --decrypt --output MTR241_20111124.htm MTR241_20111124.htm.gpg (without
I am trying to decrypt data using tripleDes. Everything looks fine but it has
I am trying to write encrypt/decrypt methods for AES 256 CBC encryption using PKCS5Padding
I have a problem while trying to decrypt encrypted assertion using SAML 2.0. The
I am trying to encrypt/decrypt a string using eith Rijndael or Aes and the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.