2

A Syntax for ConvertTo-SecureString is -

ConvertTo-SecureString [-String] [[-SecureKey] ]

I want to use this to create a secure string that is based on a user password, rather than the DPAPI.

I can create a securekey with the following code

$key = New-Object byte[](32)
$rng = [System.Security.Cryptography.RNGCryptoServiceProvider]::Create()
$rng.GetBytes($key)

but according to the docs

Valid key lengths are 16, 24, and 32 bytes

So it makes it difficult to just type a password in (that would fit into that size)

How would I convert "correcthorsebatterystaple" into a 32byte key? (such that I can then go to another machine and decrypt the secure string, using the same password)

Michael B
  • 11,887
  • 6
  • 38
  • 74
  • Seens a bit weird to have a fixed length encryption key ? But could you MD5 hash it - the output of that is 32 bytes. e.g. http://stackoverflow.com/a/10521162/478656 - I suspect that's not a great idea from a security perspective, but newer SHA hashes are not 32 bytes long, are they? – TessellatingHeckler Sep 09 '16 at 01:39
  • @TessellatingHeckler as part of my research to figure this out! it seems to be part of the AES standard - it allows 128, 192 or 256 bits of key length. The theory seems to be that you create a salt, crunch that together with the password and obtain a key from that - I'm still a distance from having code to put in an answer though – Michael B Sep 09 '16 at 01:48
  • look into PBKDF, bcrypt, or scrypt. – dandavis Sep 09 '16 at 12:54

1 Answers1

3

So it seems that this works!

$salt = "Page-Yet-Rock-Food-Also-Fear-Blind-Rub-Letter-4" # courtesy of correcthorsebatterystaple.net
$iterations = 1000

$plaintext = ConvertTo-Json -InputObject $ObjectToEncrypt 
$saltBytes = [Text.Encoding]::Unicode.GetBytes($salt) 

$password = "Bedroom-Woman-Spoon-Quarrel-7"

$deriveBytes = new-Object Security.Cryptography.Rfc2898DeriveBytes($password,$saltBytes ,$iterations)
$key = $deriveBytes.GetBytes(32) 

$SecureString = ConvertTo-SecureString -String $StringToDecrypt -Key $key  

According to the documentation of Rfc2898DeriveBytes

Rfc2898DeriveBytes takes a password, a salt, and an iteration count, and then generates keys through calls to the GetBytes method.
RFC 2898 includes methods for creating a key and initialization vector (IV) from a password and salt. You can use PBKDF2, a password-based key derivation function, to derive keys using a pseudo-random function that allows keys of virtually unlimited length to be generated. The Rfc2898DeriveBytes class can be used to produce a derived key from a base key and other parameters. In a password-based key derivation function, the base key is a password and the other parameters are a salt value and an iteration count.

Michael B
  • 11,887
  • 6
  • 38
  • 74
  • I know this is really old, but what is the `$plaintext` variable used for? It's not used anywhere in the script. Also, what is the `$StringToDecrypt` variable and where did you get it from? – beechfuzz Jul 04 '21 at 16:21