【问题标题】:How to tell if drive is BitLocker encrypted without admin privilege?如何判断驱动器是否在没有管理员权限的情况下进行了 BitLocker 加密?
【发布时间】:2014-07-13 13:34:30
【问题描述】:

出于我的目的,我只需要知道驱动器的 DOS 路径的 BitLocker 加密状态。像这样的:

enum DriveEncryptionStatus{
    Unprotected,
    Protected,
    Unknown
};

DriveEncryptionStatus = GetDriveBitlockerEncryptionStatus(L"C:\\");

我找到了 Win32_EncryptableVolume 类,不幸的是这个警告附带:

要使用 Win32_EncryptableVolume 方法,以下条件 必须满足:您必须具有管理员权限。

知道如何在不以管理员身份运行的情况下执行此操作吗?

【问题讨论】:

    标签: c++ windows winapi encryption


    【解决方案1】:

    Shell 中的任何普通用户都可以使用 BitLocker 状态。 Windows 使用 Win32 API 中的 Windows Property System 获取状态以检查未记录的 shell 属性 System.Volume.BitLockerProtection。您的程序也可以在没有海拔的情况下检查此属性。

    如果此属性的值为 1、3 或 5,则在驱动器上启用 BitLocker。任何其他值都被视为关闭。

    您可以使用 Win32 API 来检查这个 shell 属性。出于礼貌,我已从 my other answer to a similar question. 移植了我的托管实现@

    #include <shlobj.h>
    #pragma comment(lib, "shell32.lib")
    #pragma comment(lib, "propsys.lib")
    
    DriveEncryptionStatus getDriveEncryptionStatus(LPCWSTR parsingName)
    {
        IShellItem2 *drive = NULL;
        HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
        hr = SHCreateItemFromParsingName(parsingName, NULL, IID_PPV_ARGS(&drive));
        if (SUCCEEDED(hr)) {
            PROPERTYKEY pKey;
            hr = PSGetPropertyKeyFromName(L"System.Volume.BitLockerProtection", &pKey);
            if (SUCCEEDED(hr)) {
                PROPVARIANT prop;
                PropVariantInit(&prop);
                hr = drive->GetProperty(pKey, &prop);
                if (SUCCEEDED(hr)) {
                    int status = prop.intVal;
    
                    drive->Release();
    
                    if (status == 1 || status == 3 || status == 5)
                        return DriveEncryptionStatus::Protected;
                    else
                        return DriveEncryptionStatus::Unprotected;
                }
            }
        }
    
        if (drive)
            drive->Release();
    
        return DriveEncryptionStatus::Unknown;
    }
    
    int main()
    {
        DriveEncryptionStatus status = getDriveEncryptionStatus(L"C:");
        return 0;
    }
    

    【讨论】:

    • 谢谢。我会试一试。不过,在我这样做之前,您知道这些值:1 到 5 代表什么吗?
    • 相信我在 Bitlocker powershell 模块的 Microsoft.BitLocker.Structures.BitLockervolumeStatus 中找到了它们:0 - FullyDecrypted,1:FullyEncrypted,2:EncryptionInProgress,3:DecryptionInProgress,4:EncryptionSuspended,5:DecryptionSuspended, 6:FullyEncryptedWipeInProgress,7:FullyEncryptedWipeSuspended
    • 因为这是无证的,有谁知道它是否仍然适用于 Windows 10 [版本 10.0.17763.973] 及更高版本?
    • 要使代码工作,您必须在函数上方添加以下行: enum class DriveEncryptionStatus { Protected, Unprotected, Unknown }; @Weej Jamal:代码在 Windows 10 (19041) 上运行。
    • 一个 Python 实现:from win32com.propsys import propsys; bitlocker_status = propsys.SHGetPropertyStoreFromParsingName("C:").GetValue(propsys.PSGetPropertyKeyFromName("System.Volume.BitLockerProtection")).GetValue()
    【解决方案2】:

    基于this answer...

    System.Volume.BitLockerProtection 的值在 Windows 10 1909 (10.0.18363.1082) 上根据经验确定:

    | System.Volume.      | Control Panel                    | manage-bde conversion     | manage-bde     | Get-BitlockerVolume          | Get-BitlockerVolume |
    | BitLockerProtection |                                  |                           | protection     | VolumeStatus                 | ProtectionStatus    |
    | ------------------- | -------------------------------- | ------------------------- | -------------- | ---------------------------- | ------------------- |
    |                   1 | BitLocker on                     | Used Space Only Encrypted | Protection On  | FullyEncrypted               | On                  |
    |                   1 | BitLocker on                     | Fully Encrypted           | Protection On  | FullyEncrypted               | On                  |
    |                   1 | BitLocker on                     | Fully Encrypted           | Protection On  | FullyEncryptedWipeInProgress | On                  |
    |                   2 | BitLocker off                    | Fully Decrypted           | Protection Off | FullyDecrypted               | Off                 |
    |                   3 | BitLocker Encrypting             | Encryption In Progress    | Protection Off | EncryptionInProgress         | Off                 |
    |                   3 | BitLocker Encryption Paused      | Encryption Paused         | Protection Off | EncryptionSuspended          | Off                 |
    |                   4 | BitLocker Decrypting             | Decryption in progress    | Protection Off | DecyptionInProgress          | Off                 |
    |                   4 | BitLocker Decryption Paused      | Decryption Paused         | Protection Off | DecryptionSuspended          | Off                 |
    |                   5 | BitLocker suspended              | Used Space Only Encrypted | Protection Off | FullyEncrypted               | Off                 |
    |                   5 | BitLocker suspended              | Fully Encrypted           | Protection Off | FullyEncrypted               | Off                 |
    |                   6 | BitLocker on (Locked)            | Unknown                   | Unknown        | $null                        | Unknown             |
    |                   7 |                                  |                           |                |                              |                     |
    |                   8 | BitLocker waiting for activation | Used Space Only Encrypted | Protection Off | FullyEncrypted               | Off                 |
    

    【讨论】:

      【解决方案3】:

      因此,经过多次尝试在 C# 中实现这一点的失败尝试,我终于明白了这一点。一般来说,我还是 C++/C# 开发的新手,所以如果我的回答完全不相关,请告诉我。我会退出

          public static string GetBitLockerStatus()           
          {
              Process process = new Process();
              process.StartInfo.FileName = "powershell.exe";
              process.StartInfo.Arguments = "-command (New-Object -ComObject Shell.Application).NameSpace('C:').Self.ExtendedProperty('System.Volume.BitLockerProtection')"; 
              process.StartInfo.UseShellExecute = false;
              process.StartInfo.RedirectStandardOutput = true;
              process.Start();
              StreamReader reader = process.StandardOutput;
              string output = reader.ReadToEnd().Substring(0,1); //needed as output would otherwise be 1\r\n (if encrypted)
              Console.WriteLine(output);
              process.WaitForExit();
              return output;
          }
      

      【讨论】:

      • 是的,这是一种高级方法。由于这个问题被标记为 C++ 和 WinAPI,我想知道 .NET(或代理的 PowerShell)在内部使用什么来确定?
      【解决方案4】:

      在 CMD 和 Powershell 中也很容易做到 在 CMD shell 中,您可以使用此单行命令要求 Powershell 返回值作为退出代码:

      powershell -command exit 1000 + (New-Object -ComObject Shell.Application).NameSpace('C:').Self.ExtendedProperty('System.Volume.BitLockerProtection')
      

      并检查 CMD shell 中返回的%ERRORLEVEL%

      【讨论】:

      • 你看到这个问题被标记为WinAPI了吧?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      • 2019-09-25
      • 2012-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多