Managing Credentials (Part 5)

by Jan 10, 2017

When PowerShell auto-encrypts a secure string, it uses your identity as secret. Only you can decrypt the secure string. What if you want to encrypt a secret with a shared passphrase?

Here is one classic approach, using a passphrase for encryption:

# $secretKey MUST be of length 8 or 16
# anyone who knows the secret can decrypt the password 
$secretKey = 'mysecretmysecret'
$password = 'myPassword'

$SecureString = ConvertTo-SecureString -String $password -AsPlainText -Force
$RandomSecureString = ConvertTo-SecureString -String $secretKey -AsPlainText -Force
$encryptedPassword = ConvertFrom-SecureString -SecureString $SecureString -SecureKey $RandomSecureString
$encryptedPassword

The secret decryption key ($secretKey) needs to be a text with 8 or 16 characters length. Anyone who knows this key can decrypt the secret (which is why the secretKey should not be part of a script and is added to the below script only to illustrate the decryption process. You better ask for it interactively):

# this is the key to your secret
$secretKey = 'mysecretmysecret'
# this is the encrypted secret as produced by the former code
$encryptedPassword = '76492d1116743f0423413b16050a5345MgB8AEMARQAxAFgAdwBmAHcARQBvAGUAKwBOAGoAYgBzAE4AUgBnAHoARABSAHcAPQA9AHwANQA3ADYAMABjAGYAYQAwAGMANgBkADQAYQBiADYAOAAyAGYAZAA5AGYAMwA5AGYAYQBjADcANQA5ADIAYwAzADkAMAA2ADQANwA1ADcAMQA3ADMAMwBmAGMAMwBlADIAZQBjADcANgAzAGQAYQA1AGIAZABjADYAMgA2AGQANAA='

$RandomSecureString = ConvertTo-SecureString -String $secretKey -AsPlainText -Force
$securestring = $encryptedPassword | ConvertTo-SecureString -SecureKey $RandomSecureString
# Result is a secure string
$SecureString

The result is a secure string that you could use to compose a full credential:

$credential = New-Object -TypeName PSCredential('yourcompany\youruser', $SecureString)
$credential

You can also double-check the clear text secret:

 
PS C:\Users\tobwe> $credential.GetNetworkCredential().Password
myPassword
 

Note that the owner of a secure string (the one who created it) can always get back to the plain text password. This is not a security issue. The one that created the secure string already knew the secret at a given point in the past. A secure string protects sensitive data from third party, and stores it in memory in a way that no other user can touch it.

The issue with secret keys and symmetric encryption is that you need to distribute the secret key, that it needs to be protected, and can be used both for encryption and decryption.

A much safer way was introduced in PowerShell 5: Protect-CMSMessage and Unprotect-CMSMessage use digital certificates and asymmetric encryption. This way, the party encrypting a secret does not need to know the decryption key, and vice versa. The encrypting party only needs to specify who (which certificate) should be able to decrypt the secret.

Twitter This Tip! ReTweet this Tip!