0

I am writing a Powershell script that requires a privileged account to do something. Of course, I'm not going to include the password of this account in the .ps1 file in clear text so I am following this guide to create a more secure way of doing this: https://www.pdq.com/blog/secure-password-with-powershell-encrypting-credentials-part-2/

Here is the code that generates the key and encrypts the password:

$KeyFile = "\\Machine1\SharedPath\AES.key"
$Key = New-Object Byte[] 16   # You can use 16, 24, or 32 for AES
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$Key | out-file $KeyFile

$PasswordFile = "\\Machine1\SharedPath\Password.txt"
$KeyFile = "\\Machine1\SharedPath\AES.key"
$Key = Get-Content $KeyFile
$Password = "P@ssword1" | ConvertTo-SecureString -AsPlainText -Force
$Password | ConvertFrom-SecureString -key $Key | Out-File $PasswordFile

$User = "MyUserName"
$PasswordFile = "\\Machine1\SharedPath\Password.txt"
$KeyFile = "\\Machine1\SharedPath\AES.key"
$key = Get-Content $KeyFile
$MyCredential = New-Object -TypeName System.Management.Automation.PSCredential `
 -ArgumentList $User, (Get-Content $PasswordFile | ConvertTo-SecureString -Key $key)

However, the bottom of the article mentions the following:

Be sure to protect that AES key as if it were your password. Anybody who can read the AES key can decrypt anything that was encrypted with it.

Of course, anyone with access to both the .ps1 file, which is clear text by default, and the AES key file can simply read the code and use the account name and files to create a PSCredential object to do stuff with. But can they use the key file to decrypt the contents of the Password.txt file and get the account password in cleartext? I tried doing this myself with ConvertFrom-SecureString but to no avail which, I guess, makes sense?

Additional remark: The code needs to work on multiple computers, so no "local machine only" encryption mechanisms as often seen with Powershell can be used here.

Matthias
  • 115
  • 5

1 Answers1

4

First of all, the AES symmetric encryption algorithm (which ConverTo-SecureString seems to be using) is definitely not "one-way". You can always recover the plain password if you have the key, otherwise even the suggested sample wouldn't work.

The source of your problem seems to be that this sample code looks like a serious misuse of the PS/.NET API. The purpose of SecureString objects is to make in-memory attacks more difficult by hiding/deleting sensitive information if it's not in use. To achieve this SecureStrings may use encryption, but this is an implementation detail, not a service meant for this kind of "public" use. The sample may work nonetheless, you should note that (counterintuitively) encryption is done via the ConvertFrom- cmdlet, while decryption is done with ConvertTo-.

If you want a proper API for encrpytion start here.

buherator
  • 1,730
  • 1
  • 9
  • 15
  • Interesting. Would it be possible to provide some code to actually extract the password from the "encrypted" password.txt file? Definitely going to check out the AesManaged class as well, thanks. – Matthias Jun 28 '18 at 08:03
  • This is kind of a hacky solution: `Write-Host $MyCredential.GetNetworkCredential().Password` - see this blog post for more info: https://blogs.technet.microsoft.com/heyscriptingguy/2013/03/26/decrypt-powershell-secure-string-password/ – buherator Jun 28 '18 at 08:23