BitLocker with Windows DPAPI Encryption Key Management
We have a need to enforce resting encryption on an iSCSI LUN that is accessible from within a Hyper-V virtual machine.
We have implementing a working solution using BitLocker, using Windows Server 2012 on a Hyper-V Virtual Server which has iSCSI access to a LUN on our SAN. We were able to successfully do this by using the "floppy disk key storage" hack as defined in THIS POST. However, this method seems "hokey" to me.
In my continued research, I found out that the Amazon Corporate IT team published a WHITEPAPER that outlined exactly what I was looking for in a more elegant solution, without the "floppy disk hack". On page 7 of this white paper, they state that they implemented Windows DPAPI Encryption Key Management to securely manage their BitLocker keys. This is exactly what I am looking to do, but they stated that they had to write a script to do this, yet they don't provide the script or even any pointers on how to create one.
Does anyone have details on how to create a "script in conjunction with a service and a key-store file protected by the server’s machine account DPAPI key" (as they state in the whitepaper) to manage and auto-unlock BitLocker volumes? Any advice is appreciated.
--- EDIT 1 ---
Based on Evan’s response below, here is what I have figured out, but I'm still stuck.
I assume that using PsExec and running the following command, that PowerShell is running under the System account and that it will “encrypt the string w/ the machine account's password” as Evan stated. Is this correct?
PsExec.exe -i -s Powershell.exe
Then from within PS, (using this post as a reference) I run this command to generate the SecureString password:
ConvertTo-SecureString -String "MyBitLockerPassword" -AsPlainText –Force | ConvertFrom-SecureString | Out-File C:\securestring.txt
That gives me a file containing the secure string in the format of “01000000d08c…” (a total of 524 characters). Then, I can now create a Schedule Task to run on boot that uses the following to load the password (as a SecureString) and pass it to the Unlock-BitLocker command:
$SecureBitLockerPassword = Get-Content C:\securestring.txt | ConvertTo-SecureString
Unlock-BitLocker -MountPoint "E:" -Password $ SecureBitLockerPassword
However, if I’m simply storing the encrypted password as a file on the hard drive, what’s the point of the encrypting and decrypting the password? Wouldn't that be just as insecure as storing the password in plain text and using the following (without the need to create the secure string file)?
$SecureString = ConvertTo-SecureString " MyBitLockerPassword " -AsPlainText –Force
Unlock-BitLocker -MountPoint "E:" -Password $SecureString
How else would you approach this? Where could I store the SecureString key so that only the System account can access it?
It looks like all Amazon is doing is storing the Bitlocker keys in DPAPI in the SYSTEM context. While this is much less secure than storing the keys in a TPM (because the plaintext key can be retrieved by any service running as SYSTEM versus a key stored in a TPM which cannot be recovered) if the TPM isn't exposed to the virtual machine this is probably your only option.
To accomplish something similar to what they're describing I'd probably use the ConvertFrom-SecureString
and complimentary ConvertTo-SecureString
PowerShell APIs. Per the Microsoft docs the ConvertFrom-SecureString
cmdlet uses DPAPI if no static key is specified. Run the script in the SYSTEM context and DPAPI will encrypt your string w/ the machine account's password.
From that point it's a matter of using the manage-bde
tool to unlock the drive using the retrieved password (e.g. manage-bde -unlock x: -password
)