Encrypting Passwords in PowerShell With Your Own Key

The security of passwords and strings is a little confusing in Microsoft Windows —and much of it uses legacy methods. For strings we can…

Encrypting Passwords in PowerShell With Your Own Key

The security of passwords and strings is a little confusing in Microsoft Windows —and much of it uses legacy methods. For strings we can encrypt them into secure strings using the Data Protection Application Programming Interface (DPAPI). But, what if we want to use our own keys?

In terms of the encryption methods, it has been discovered that the DPAPI method depend on the operating system version:

  • Windows 2000 uses RC4 and HMAC-SHA-1 with one round of PBKDF2. Approximate security strength: 95,000 passwords/second.
  • Window XP uses 3DES and HMAC-SHA-1 with 4000 rounds of PBKDF2. Approximate security strength: 4,000 passwords/second.
  • Windows Vista uses 3DES and HMAC-SHA-1 with 24000 rounds of PBKDF2. Approximate security strength: 12 passwords/second.
  • Windows 7 and Windows 10 use 256-bit AES-CBC and HMAC-SHA-512 with 5,600 rounds of PBKDF2. Approximate security strength: 10 passwords/second.

To create a secure string [here]:

$pwd = 'qwerty123'
$securepwd = ConvertTo-SecureString -String $pwd -AsPlainText -Force
$encryptedpwd = ConvertFrom-SecureString -SecureString $securepwd
"Input: "+ $pwd
"Encrypted: " + $encryptedpwd
$dec = ConvertFrom-SecureString -SecureString $securepwd -AsPlainText
"Decrypted: " + $dec

A sample run shows:

Input: qwerty123
Encrypted: 01000000d08c9ddf0115d1118c7a00c04fc297eb01000000e04794a8b647a145b23d1d0191029caf0000000002000000000010660000000100002000000019e358c8ffef427a6002feba277e5c56846fd6cdc34c0d3f61f1a33744023110000000000e8000000002000020000000031df856aff5e89017b6395edf8117ab90754cac0e391e7e9f42bd5fa42f1690200000009e0e10ffdd971a1eb4ce47a2de65dc1109cf6b2759ef23900f60212458920f644000000046f759f858c03ca2b3245406412a7c2ddc7ff34be74c5ea0a4c5ee501566980d8785d328908f26ae5a0484636d70e69992cc019503dbc34963564478590329df
Decrypted: qwerty123

The magic number of encrypted data is:

01 00 00 00 D0 8C 9D DF 01 15 D1 11 8C 7A 00 C0 4F C2 97 EB

If we parse the encrypted content we get:

01000000d08c9ddf0115d1118c7a00c04fc297eb
01000000e04794a8
b647a145b23d1d0191029caf
00000000
020000000000106600000001000020000000
19e358c8ffef427a6002feba277e5c56846fd6cdc34c0d3f61f1a33744023110000000000e8000000002000020000000031df856aff5e89017b6395edf8117ab90754cac0e391e7e9f42bd5fa42f1690200000009e0e10ffdd971a1eb4ce47a2de65dc1109cf6b2759ef23900f60212458920f644000000046f759f858c03ca2b3245406412a7c2ddc7ff34be74c5ea0a4c5ee501566980d8785d328908f26ae5a0484636d70e69992cc019503dbc34963564478590329df

If we try again we get:

01000000d08c9ddf0115d1118c7a00c04fc297eb
01000000e04794a8
b647a145b23d1d0191029caf
00000000
020000000000106600000001000020000000
ef3f11f06e2a53976217612a25e9b0d85b3b4e4adc746050030b4307ca87a2b3000000000e8000000002000020000000dc18f2b55e92e48db9558b72c6a0b6a81b705c4e1c8755af48d2b7c7b3dabc802000000080fca6221dcc16a7d383ab939fe01eaa313f8d5fae59180b29cbfeb8e5f1a1b3400000004be833c22436048561b8cd40849020104406db3dbd6bd224f263108934cada659e81046b6f0ee75a9a70dae09c1f33da048d6990d518896c589a5fa9adcd44df

But, what if we want to encrypt the string with our own password. Well, with this, we can generate our own key with PBKDF2, and then use the generated key to encrypt the secure string. For this we can take the secure strong, then use the -key option:

$EncryptedPW = ConvertFrom-SecureString $SecureString -Key $keyder

The following is the coding [here]:

$password =$Args[0]
$salt = $Args[1]
$iterations = [int]$Args[2]
$hash = $Args[3]
$size=$Args[4]
$saltBytes = [Text.Encoding]::UTF8.GetBytes($salt)
$keyder=[Security.Cryptography.Rfc2898DeriveBytes]::Pbkdf2($password,$saltBytes,$iterations,$hash,$size)
"Password: "+$password
"Salt: "+$salt
"Iterations: "+$iterations
"Hash method: "+$hash
"Size: "+$size
"`nKey derivation (Hex): "+[System.Convert]::ToHexString($keyder)
"Key derivation (Hex): "+[System.Convert]::ToBase64String($keyder)
$SecureString = ConvertTo-SecureString -String $password -AsPlainText -Force
$SecureStringVal = ConvertFrom-SecureString -SecureString $SecureString
$EncryptedPW = ConvertFrom-SecureString $SecureString -Key $keyder

"Secure string: "+$SecureStringVal
"Encrypted password: "+$EncryptedPW
$EncryptedPW1 = ConvertTo-SecureString -String $EncryptedPW -Key $keyder
$pass = ConvertFrom-SecureString -SecureString $EncryptedPW1 -AsPlainText
"Decrypted Password: "+$pass

A sample run shows [here]:

Password: qwerty
Salt: test
Iterations: 500
Hash method: SHA256
Size: 32
Key derivation (Hex): 21B10ED2B006D1F0826B4A2E3A16841D614ACCE155F77FFA2B17A0C1E48F92D8
Key derivation (Hex): IbEO0rAG0fCCa0ouOhaEHWFKzOFV93/6KxegweSPktg=
Secure string: 01000000d08c9ddf0115d1118c7a00c04fc297eb01000000d1632283ab62d548af37fa9aaf5e7d3e00000000020000000000106600000001000020000000531ee2f83b547fd5f7642bbc603de980a4969233f79a1f1869d0122de390b158000000000e8000000002000020000000df47b0ca5242c289bdb75696dedeb549c58eb3c1fb2327693b4ddccd04791c7710000000203bda1f0b836e647640b5d6619b3b2040000000b76dd6a773c15ce9378c2451559ad5532cef403336511702b29be4d6433d17bb77fcf30d1ce50f9855e86ee175aeb1769b1cbd82142f648de1bf5e1b0c19f2ee
Encrypted password: 76492d1116743f0423413b16050a5345MgB8AEwAZQBaAHoAYwBrAG8AWQByAGQAMgBZAGcAbwBHAG8ARgA5AEgASgB6AFEAPQA9AHwAMgA0ADIAYQBmADIAOQBkAGQAMAAwADIANgBmAGIAMQBmADkAMQA0AGEAMwBmADAAZABhADYANwA5AGUAOABkAA==
Decrypted Password: qwerty

There is more PowerShell things here:

https://asecuritysite.com/powershell