PowerShell Script: Encrypting / Decrypting A String – Function Encrypt-String
By: Brenton Blawat
The encryption and decryption of strings is essential when creating an enterprise product that has clear text passwords. This function displays how to encrypt and decrypt a string using Powershell using Richard’s code located at http://poshcode.org/116. While I found his code very useful, he didn’t explain the syntax and is why I am reposting this with the proper information.
I also decided to make this into an endless loop for an administrator to use to encrypt multiple passwords in a row. I found this to be useful as I never had to encrypt just one password.
Important for your security!!
In order to ensure your application is safe from an attacker be certain to perform each of the following:
1. Change the $salt variable and $init variables. These variables should be at least 8 characters long but should be changed or your application is subject to a brute force attack if someone determines you are using my code!
1: function Encrypt-String($String, $Passphrase, $salt="SaltCrypto", $init="IV_Password", [switch]$arrayOutput)
2. Change the Passphrase that is passed into the function. I suggest a 12-18 character Passphrase to prevent the above brute force attack.
1: $encrypted = Encrypt-String $string "MyStrongPassword"
3. Be sure to pass the right Passphrase into the function for decryption. If you pass the wrong key into the function, you will not get the correct password returned from the function.
Function for Encrypting / Decrypting A String in PowerShell
1: #################
2: # Powershell Allows The Loading of .NET Assemblies
3: # Load the Security assembly to use with this script
4: #################
5: [Reflection.Assembly]::LoadWithPartialName("System.Security")
6:
7: #################
8: # This function is to Encrypt A String.
9: # $string is the string to encrypt, $passphrase is a second security "password" that has to be passed to decrypt.
10: # $salt is used during the generation of the crypto password to prevent password guessing.
11: # $init is used to compute the crypto hash -- a checksum of the encryption
12: #################
13: function Encrypt-String($String, $Passphrase, $salt="SaltCrypto", $init="IV_Password", [switch]$arrayOutput)
14: {
15: # Create a COM Object for RijndaelManaged Cryptography
16: $r = new-Object System.Security.Cryptography.RijndaelManaged
17: # Convert the Passphrase to UTF8 Bytes
18: $pass = [Text.Encoding]::UTF8.GetBytes($Passphrase)
19: # Convert the Salt to UTF Bytes
20: $salt = [Text.Encoding]::UTF8.GetBytes($salt)
21:
22: # Create the Encryption Key using the passphrase, salt and SHA1 algorithm at 256 bits
23: $r.Key = (new-Object Security.Cryptography.PasswordDeriveBytes $pass, $salt, "SHA1", 5).GetBytes(32) #256/8
24: # Create the Intersecting Vector Cryptology Hash with the init
25: $r.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15]
26:
27: # Starts the New Encryption using the Key and IV
28: $c = $r.CreateEncryptor()
29: # Creates a MemoryStream to do the encryption in
30: $ms = new-Object IO.MemoryStream
31: # Creates the new Cryptology Stream --> Outputs to $MS or Memory Stream
32: $cs = new-Object Security.Cryptography.CryptoStream $ms,$c,"Write"
33: # Starts the new Cryptology Stream
34: $sw = new-Object IO.StreamWriter $cs
35: # Writes the string in the Cryptology Stream
36: $sw.Write($String)
37: # Stops the stream writer
38: $sw.Close()
39: # Stops the Cryptology Stream
40: $cs.Close()
41: # Stops writing to Memory
42: $ms.Close()
43: # Clears the IV and HASH from memory to prevent memory read attacks
44: $r.Clear()
45: # Takes the MemoryStream and puts it to an array
46: [byte[]]$result = $ms.ToArray()
47: # Converts the array from Base 64 to a string and returns
48: return [Convert]::ToBase64String($result)
49: }
50:
51: function Decrypt-String($Encrypted, $Passphrase, $salt="SaltCrypto", $init="IV_Password")
52: {
53: # If the value in the Encrypted is a string, convert it to Base64
54: if($Encrypted -is [string]){
55: $Encrypted = [Convert]::FromBase64String($Encrypted)
56: }
57:
58: # Create a COM Object for RijndaelManaged Cryptography
59: $r = new-Object System.Security.Cryptography.RijndaelManaged
60: # Convert the Passphrase to UTF8 Bytes
61: $pass = [Text.Encoding]::UTF8.GetBytes($Passphrase)
62: # Convert the Salt to UTF Bytes
63: $salt = [Text.Encoding]::UTF8.GetBytes($salt)
64:
65: # Create the Encryption Key using the passphrase, salt and SHA1 algorithm at 256 bits
66: $r.Key = (new-Object Security.Cryptography.PasswordDeriveBytes $pass, $salt, "SHA1", 5).GetBytes(32) #256/8
67: # Create the Intersecting Vector Cryptology Hash with the init
68: $r.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15]
69:
70:
71: # Create a new Decryptor
72: $d = $r.CreateDecryptor()
73: # Create a New memory stream with the encrypted value.
74: $ms = new-Object IO.MemoryStream @(,$Encrypted)
75: # Read the new memory stream and read it in the cryptology stream
76: $cs = new-Object Security.Cryptography.CryptoStream $ms,$d,"Read"
77: # Read the new decrypted stream
78: $sr = new-Object IO.StreamReader $cs
79: # Return from the function the stream
80: Write-Output $sr.ReadToEnd()
81: # Stops the stream
82: $sr.Close()
83: # Stops the crypology stream
84: $cs.Close()
85: # Stops the memory stream
86: $ms.Close()
87: # Clears the RijndaelManaged Cryptology IV and Key
88: $r.Clear()
89: }
90:
91: # This clears the screen of the output from the loading of the assembly.
92: cls
93:
94: # $me will never = 1, so It will run indefinately
95: $me = 0
96: write-host "To End This Application, Close the Window"
97: Write-host ""
98: do
99: {
100: # Prompt the user for the password
101: $string = read-host "Please Enter User Password"
102: # Encrypt the string and store it into the $encrypted variable
103: $encrypted = Encrypt-String $string "MyStrongPassword"
104: # Write result to the screen
105: write-host "Encrypted Password is: $encrypted"
106: write-host ""
107:
108: write-host "Testing Decryption of Password..."
109:
110: # Decrypts the string and stores the decrypted value in $decrypted
111: $decrypted = Decrypt-String $encrypted "MyStrongPassword"
112: # Writes the decrpted value to the screen
113: write-host "Decrypted Password is: $decrypted"
114: write-host ""
115: }
116:
117: while ($me -ne 1)
To use this Function:
Start > Run > Type powershell.exe –noexit c:\location\EncryptDecryptString.ps1
** When you are done close the window.
Function for Encrypting Username and Passwords in PowerShell
You will notice that I changed the Passphrase for both the username and the password. This is not necessary, however, it adds another layer of security. Try not to encrypt everything with the same passphrase. If one item gets compromised, everything encrypted under that passphrase is compromised.
1: #################
2: # Powershell Allows The Loading of .NET Assemblies
3: # Load the Security assembly to use with this script
4: #################
5: [Reflection.Assembly]::LoadWithPartialName("System.Security")
6:
7: #################
8: # This function is to Encrypt A String.
9: # $string is the string to encrypt, $passphrase is a second security "password" that has to be passed to decrypt.
10: # $salt is used during the generation of the crypto password to prevent password guessing.
11: # $init is used to compute the crypto hash -- a checksum of the encryption
12: #################
13: function Encrypt-String($String, $Passphrase, $salt="SaltCrypto", $init="IV_Password", [switch]$arrayOutput)
14: {
15: # Create a COM Object for RijndaelManaged Cryptography
16: $r = new-Object System.Security.Cryptography.RijndaelManaged
17: # Convert the Passphrase to UTF8 Bytes
18: $pass = [Text.Encoding]::UTF8.GetBytes($Passphrase)
19: # Convert the Salt to UTF Bytes
20: $salt = [Text.Encoding]::UTF8.GetBytes($salt)
21:
22: # Create the Encryption Key using the passphrase, salt and SHA1 algorithm at 256 bits
23: $r.Key = (new-Object Security.Cryptography.PasswordDeriveBytes $pass, $salt, "SHA1", 5).GetBytes(32) #256/8
24: # Create the Intersecting Vector Cryptology Hash with the init
25: $r.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15]
26:
27: # Starts the New Encryption using the Key and IV
28: $c = $r.CreateEncryptor()
29: # Creates a MemoryStream to do the encryption in
30: $ms = new-Object IO.MemoryStream
31: # Creates the new Cryptology Stream --> Outputs to $MS or Memory Stream
32: $cs = new-Object Security.Cryptography.CryptoStream $ms,$c,"Write"
33: # Starts the new Cryptology Stream
34: $sw = new-Object IO.StreamWriter $cs
35: # Writes the string in the Cryptology Stream
36: $sw.Write($String)
37: # Stops the stream writer
38: $sw.Close()
39: # Stops the Cryptology Stream
40: $cs.Close()
41: # Stops writing to Memory
42: $ms.Close()
43: # Clears the IV and HASH from memory to prevent memory read attacks
44: $r.Clear()
45: # Takes the MemoryStream and puts it to an array
46: [byte[]]$result = $ms.ToArray()
47: # Converts the array from Base 64 to a string and returns
48: return [Convert]::ToBase64String($result)
49: }
50:
51: function Decrypt-String($Encrypted, $Passphrase, $salt="SaltCrypto", $init="IV_Password")
52: {
53: # If the value in the Encrypted is a string, convert it to Base64
54: if($Encrypted -is [string]){
55: $Encrypted = [Convert]::FromBase64String($Encrypted)
56: }
57:
58: # Create a COM Object for RijndaelManaged Cryptography
59: $r = new-Object System.Security.Cryptography.RijndaelManaged
60: # Convert the Passphrase to UTF8 Bytes
61: $pass = [Text.Encoding]::UTF8.GetBytes($Passphrase)
62: # Convert the Salt to UTF Bytes
63: $salt = [Text.Encoding]::UTF8.GetBytes($salt)
64:
65: # Create the Encryption Key using the passphrase, salt and SHA1 algorithm at 256 bits
66: $r.Key = (new-Object Security.Cryptography.PasswordDeriveBytes $pass, $salt, "SHA1", 5).GetBytes(32) #256/8
67: # Create the Intersecting Vector Cryptology Hash with the init
68: $r.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15]
69:
70:
71: # Create a new Decryptor
72: $d = $r.CreateDecryptor()
73: # Create a New memory stream with the encrypted value.
74: $ms = new-Object IO.MemoryStream @(,$Encrypted)
75: # Read the new memory stream and read it in the cryptology stream
76: $cs = new-Object Security.Cryptography.CryptoStream $ms,$d,"Read"
77: # Read the new decrypted stream
78: $sr = new-Object IO.StreamReader $cs
79: # Return from the function the stream
80: Write-Output $sr.ReadToEnd()
81: # Stops the stream
82: $sr.Close()
83: # Stops the crypology stream
84: $cs.Close()
85: # Stops the memory stream
86: $ms.Close()
87: # Clears the RijndaelManaged Cryptology IV and Key
88: $r.Clear()
89: }
90:
91: # This clears the screen of the output from the loading of the assembly.
92: cls
93:
94: # $me will never = 1, so It will run indefinately
95: $me = 0
96: write-host "To End This Application, Close the Window"
97: Write-host ""
98: do
99: {
100: # Prompt the user for the password
101:
102: $ustring = read-host "(Case Sensitive) Please Enter Username"
103: $pstring = read-host "(Case Sensitive) Please Enter User Password"
104: # Encrypt the string and store it into the $encrypted variable
105: $uencrypted = Encrypt-String $ustring "U_MyStrongPassword"
106: $pencrypted = Encrypt-String $pstring "P_MyStrongPassword"
107:
108: # Write result to the screen
109: write-host "Encrypted Username is: $uencrypted"
110: write-host ""
111: write-host "Encrypted Password is: $pencrypted"
112: write-host ""
113:
114: write-host "Testing Decryption of Username / Password..."
115: write-host ""
116: # Decrypts the string and stores the decrypted value in $decrypted
117: $udecrypted = Decrypt-String $uencrypted "U_MyStrongPassword"
118: $pdecrypted = Decrypt-String $pencrypted "P_MyStrongPassword"
119:
120: # Writes the decrpted value to the screen
121: write-host "Decrypted Password is: $udecrypted"
122: write-host ""
123: write-host "Decrypted Password is: $pdecrypted"
124:
125: }
126:
127: while ($me -ne 1)
To use this Function:
Start > Run > Type powershell.exe –noexit c:\location\EncryptDecryptStringUP.ps1
** When you are done close the window.



PShellExec is a free utility that encrypts and executes any data sensitive PowerShell scripts.
Les Papier
January 7, 2011
So that no one else wastes their time, I will explain what this product does.
#1 PShellExec a command line based tool that you need to INPUT A PASSWORD both directions. So if you’re trying to script the encryption and decryption of the powershell script…. the password has to be in clear text or base… which is basically the same thing as my above script when you’re scripting it.
#2 De-compiling the PshellExe.exe, I found that you are using the same cryptology mechanism that I am using in my Powershell script: (Code from exe: System.Reflection RijndaelManaged)
#3 You complied it into an exe… and it needs to be distributed to every system on the network unlike Powershell which is natively installed on Windows 7 + Server 2008 system. No small or large organization would dare touch an unsigned exe with no version information from an author-less developer… “Paperless” is not signing your code and really gives the product no cred.
http://arthropoda.southernfriedscience.com/wp-content/uploads/2009/11/facepalm.jpg
I suggest staying far away from this application.
brentblawat
January 7, 2011
How do you use the encrypted password once it’s encrypted?
Nick
February 14, 2011
Nick,
The “function” password (MyStrongPassword) is not encrypted; the “user password” in my example is encrypted. After running the script, the script will output the value of the “User Password” in it’s encrypted state. When you run the decryption function, the script will output the decrypted value of the “User password”.
Remember you have to use the same “function” password for the encryption and decryption calls:
Encrypt-String $encrypted “MyStrongPassword”
Decrypt-String $encrypted “MyStrongPassword”
If you don’t want to automate the encryption and decryption process, the TRUE and secure way to do it is prompt for a “function” password by doing:
$passstr = read-host “(Case Sensitive) Please Enter The Script Password”
$encrypted = Encrypt-String $encrypted $passstr
OR
$passstr = read-host “(Case Sensitive) Please Enter The Script Password”
$decrypted = Decrypt-String $encrypted $passstr
Let me know if this answers your question.
-Brenton
brentblawat
February 14, 2011