blog.majcica.com Open in urlscan Pro
2a01:238:20a:202:1159::  Public Scan

URL: http://blog.majcica.com/2017/11/07/persisting-sensitive-information-with-powershell/
Submission: On August 15 via manual from CH — Scanned from DE

Form analysis 2 forms found in the DOM

POST http://blog.majcica.com/wp-comments-post.php

<form action="http://blog.majcica.com/wp-comments-post.php" method="post" id="commentform" class="comment-form">
  <p class="comment-notes"><span id="email-notes">Your email address will not be published.</span> <span class="required-field-message" aria-hidden="true">Required fields are marked <span class="required" aria-hidden="true">*</span></span></p>
  <p class="comment-form-comment"><label for="comment">Comment <span class="required" aria-hidden="true">*</span></label> <textarea id="comment" name="comment" cols="45" rows="8" maxlength="15360" required="" minlength="15"></textarea></p>
  <p class="comment-form-author"><label for="author">Name <span class="required" aria-hidden="true">*</span></label> <input id="author" name="author" type="text" value="" size="30" maxlength="245" required=""></p>
  <p class="comment-form-email"><label for="email">Email <span class="required" aria-hidden="true">*</span></label> <input id="email" name="email" type="email" value="" size="30" maxlength="100" aria-describedby="email-notes" required=""></p>
  <p class="comment-form-url"><label for="url">Website</label> <input id="url" name="url" type="url" value="" size="30" maxlength="200"></p>
  <p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes"> <label for="wp-comment-cookies-consent">Save my name, email, and website in this browser for the next time
      I comment.</label></p>
  <p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="Post Comment"> <input type="hidden" name="comment_post_ID" value="1233" id="comment_post_ID">
    <input type="hidden" name="comment_parent" id="comment_parent" value="0">
  </p>
  <noscript><input type="hidden" name="JS04X7" value="NS1"></noscript>
  <noscript>
    <p><strong>Currently you have JavaScript disabled. In order to post comments, please make sure JavaScript and Cookies are enabled, and reload the page.</strong>
      <a href="http://enable-javascript.com/" rel="nofollow external">Click here for instructions on how to enable JavaScript in your browser.</a></p>
  </noscript>
</form>

GET http://blog.majcica.com/

<form role="search" method="get" class="search-form" action="http://blog.majcica.com/">
  <label>
    <span class="screen-reader-text">Search for:</span>
    <input type="search" class="search-field" placeholder="Search …" value="" name="s">
  </label>
  <input type="submit" class="search-submit" value="Search">
</form>

Text Content

Skip to content


MUMMY'S BLOG


AS MOTHER MADE IT – MARIO MAJČICA'S WEB LOG

 * About Mario Majčica
 * Contact Me


PERSISTING SENSITIVE INFORMATION WITH POWERSHELL

It often happens that I need to persist a password or another sensitive
information strings in a file or database. When it happens I can never recall
what was exactly the command I used to do so in the past. That’s why I decided
to encapsulate the two operation of encrypting and decrypting a string in a
cmdlet so that the next time I can just check my blog post.

A small preface about the operation of encryption. It is based on the
ConvertTo-SecureString cmdlet which on its own uses Advanced Encryption Standard
(AES) encryption algorithm. Supported key lengths by the AES encryption
algorithm in this case are 128, 192, or 256 bits and they do depend on the
specified key length.

function Protect-String()
{
    [CmdletBinding()]
    param
    (
        [string][parameter(Mandatory = $true)]$String,
        [string][parameter(Mandatory = $true)]$Key
    )
    BEGIN { }
    PROCESS
    {      
        if (([system.Text.Encoding]::Unicode).GetByteCount($Key) * 8 -notin 128,192,256)
        {
            throw "Given encription key has an invalid lenght. The specified key must have a length of 128, 192, or 256 bits."
        }

        $secureKey = ConvertTo-SecureString -String $Key -AsPlainText -Force
        
        return ConvertTo-SecureString $String -AsPlainText -Force | ConvertFrom-SecureString -SecureKey $secureKey
    }
    END { }
}

As you can see, there are two required parameters, string that you are trying to
encrypt and the key to use to encrypt it. As mentioned above, specified key must
have a length of 128, 192, or 256 bits. This translate in a string with length
respectively equal to 8, 12 or 16 chars. The calculation is simple, strings
inside PowerShell are represented as 16-bit Unicode, instances of .NET’s
System.String class, thus 16 bits per character. Knowing this, the maths is
easy.
For record, if we haven’t specified any key, the Windows Data Protection API
(DPAPI) would be used to encrypt the standard string representation and we
wouldn’t be capable of decrypting our string on a different computer.
After we invoke our cmdlet, we will get back the encrypted string. We can then
persist that information safely in, at example, our configuration file or a
database field.

Once we need to read our value back we can use the following cmdlet:

function Unprotect-String()
{
    [CmdletBinding()]
    param
    (
        [string][parameter(Mandatory = $true)]$String,
        [string][parameter(Mandatory = $true)]$Key
    )
    BEGIN { }
    PROCESS
    {
        if (([system.Text.Encoding]::Unicode).GetByteCount($Key) * 8 -notin 128,192,256)
        {
            throw "Given encription key has an invalid lenght. The specified key must have a length of 128, 192, or 256 bits."
        }

        $secureKey = ConvertTo-SecureString -String $Key -AsPlainText -Force
        $secureString = ConvertTo-SecureString $String -SecureKey $secureKey

        $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "dummy", $secureString

        return $credential.GetNetworkCredential().Password
    }
    END { }
}

Passing in the encrypted string and the key that should be used to decrypt the
information, this cmdlet will return the decrypted string.

Following an example:

$password = "My strong super password"
$key = '1234567890123456'

$encryptedString = Protect-String $password $key

Unprotect-String $encryptedString $key

You can expect to see outputted console the “My strong super password”.



That’s all folks. Keep your sensitive information safe!

TwitterLinkedInFacebookWhatsAppShare

Tagged as: AES, ConvertFrom-SecureString, ConvertTo-SecureString, encryption,
password, PowerShell

Categorized in: Cryptography, PowerShell, Uncategorized

November 7, 2017 Mario Majcica3 Comments


POST NAVIGATION

TextTransform issues after VS Project Upgrade
Next Post


3 THOUGHTS ON “PERSISTING SENSITIVE INFORMATION WITH POWERSHELL”

 1. Kala says:
    December 15, 2017 at 14:18
    
    Hello,
    It doesnt work, returns : ##[error]A parameter cannot be found that matches
    parameter name ‘ToSession’
    
    Any ideas?
    
    Thanks in advance
    
    Reply
    1. Mario Majcica says:
       December 15, 2017 at 14:30
       
       Hi Kala,
       
       I just re-run all of the samples I do provide and they work as described.
       Where is the ToSession parameter coming from? Seems like you are using a
       Copy-Item cmdlet or similar ones that do accept the session object and
       you are running an older version of PowerShell (as ToSession parameter is
       available only on PSv5).
       
       Mario
       
       Reply
       
    2. Mario Majcica says:
       December 15, 2017 at 14:34
       
       It seems you comment ended up in the wrong post. This seems relevant to
       my WinRm Copy File extension. Also, given the error I do suppose that the
       build server or the machine you are copying onto, are not running
       PowerShell v5.
       
       Mario
       
       Reply
       
    


LEAVE A REPLY CANCEL REPLY

Your email address will not be published. Required fields are marked *

Comment *

Name *

Email *

Website

Save my name, email, and website in this browser for the next time I comment.



Currently you have JavaScript disabled. In order to post comments, please make
sure JavaScript and Cookies are enabled, and reload the page. Click here for
instructions on how to enable JavaScript in your browser.

© 2015 Mario Majčica All Rights Reserved

Decode Theme by Macho Themes

Search for:


RECENT POSTS

 * Signing Git Commits
 * Building Visual Studio projects with DevEnv.com
 * Starting a TFS release via REST API
 * Azure DevOps extension for XL Deploy
 * Download a file with TypeScript
 * Node10 provider available for Agent v2.144.0
 * Uploading XL Deploy DAR package via TypeScript
 * Living Documentation and test reports in VSTS/TFS pipelines
 * Deploy SSIS packages from TFS/VSTS Build/Release
 * Provisioning WebDeploy in VSTS/TFS release via DSC script
 * Using global application host file in Visual Studio 2015+
 * Get Users SID with PowerShell
 * Joining strings in pipeline
 * Automate setting ‘Retain indefinitely’ flag on your releases
 * Uploading build/release tasks to VSTS
 * Managing VSTS/TFS Release Definition Variables from PowerShell
 * Using Windows Machine File Copy (WinRM) VSTS extension
 * (no title)
 * Persisting sensitive information with PowerShell
 * TextTransform issues after VS Project Upgrade
 * XL Deploy in VSTS/TFS build/release pipelines
 * Using Git with self-signed certificate at the user level
 * VSTS/TFS Agents behind a proxy
 * TFS Tips from the Trenches
 * Working with TFS in IntelliJ IDEA via VSTS Plugin


CATEGORIES

 * .NET (19)
   * ASP.NET (6)
   * C# (14)
   * DevExpress (3)
   * Moq (1)
   * MSTest (2)
   * TPL (1)
   * WCF (2)
 * Articles (15)
 * Azure DevOps (4)
 * Best Practice (12)
 * Cisco (1)
   * IOS (1)
 * CodedUI (5)
 * Cryptography (4)
 * Development (4)
   * SQL (2)
 * Git (2)
 * Hardware (1)
 * IIS (2)
 * IntelliJ IDEA (1)
 * JavaScript (1)
 * Networking (1)
 * News (1)
 * Nexus (3)
 * NodeJs (2)
 * PowerShell (13)
 * Security (9)
 * SonarQube (3)
 * SpecFlow (2)
 * Testing (5)
 * TFS (29)
   * TFS 2015 (12)
   * TFS 2017 (4)
 * Tips and Tricks (2)
 * TypeScript (3)
 * Uncategorized (42)
 * Unit test (4)
 * Visual Studio (12)
   * Nuget (2)
   * Templates (1)
   * VSIX (3)
 * VSTS (9)
 * Windows 8 (1)
 * WiX (1)
 * XebiaLabs (7)
   * XL Deploy (5)
   * XL TestView (2)


META

 * Log in
 * Entries feed
 * Comments feed
 * WordPress.org

✓
Thanks for sharing!
AddToAny
More…