PowerShell Script: Encrypting / Decrypting A String – Function Encrypt-String

Posted on March 20, 2010. Filed under: Powershell Tangents |

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

Download PS1 Here

   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

Download PS1 Here

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.

Make a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

4 Responses to “PowerShell Script: Encrypting / Decrypting A String – Function Encrypt-String”

RSS Feed for Business and Information Technology Tangents Comments RSS Feed

PShellExec is a free utility that encrypts and executes any data sensitive PowerShell scripts.

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.

How do you use the encrypted password once it’s encrypted?

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


Where's The Comment Form?

    About

    Business and Information Technology Tangents is dedicated to providing quality content while informing the world about technology.

    RSS

    Subscribe Via RSS

    • Subscribe with Bloglines
    • Add your feed to Newsburst from CNET News.com
    • Subscribe in Google Reader
    • Add to My Yahoo!
    • Subscribe in NewsGator Online
    • The latest comments to all posts in RSS

    Meta

Liked it here?
Why not try sites on the blogroll...

Follow

Get every new post delivered to your Inbox.