Part One – Computing email address hash value using Windows PowerShell

I was recently discussing tracking email addresses and in particular protecting sensitive information and ensuring that the email address may not be re-used on deactivation. This got me thinking of how we could achieve this using Windows PowerShell.

As the advanced function required an email address I wanted to validate the  parameter specified for an email address so that is was valid. In the initial scenario I used a match based on regular expression as below. The regex pattern should match 99.9% of valid email addresses, but only allows for letters, digits and a couple of special characters. The official definition specified in RFC 5322 is far more complex

  (?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*
  |  "(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]
      |  \\[\x01-\x09\x0b\x0c\x0e-\x7f])*")
@ (?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?
  |  \[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}
       (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:
          (?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]
          |  \\[\x01-\x09\x0b\x0c\x0e-\x7f])+)
     \])


[CmdletBinding()]
Param (
[Parameter(Mandatory=$True, ValueFromPipeline=$True, HelpMessage="Enter an email address to compute hash")]
[ValidateScript({"\b[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}\b"})]
[String[]]$Email
)

However, I found that this generated what could be considered as an unfriendly error exception message, if the validation of the patten was returned as ‘false’.

 Cannot validate argument on parameter 'Email'. The "$_ -match "\b[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}\b"" validation script for the argument with value "someone@where" did not return a result of True

Therefore I decided to modify the script block for the parameter validation to throw an error if the validation of the pattern was returned as ‘false’,


[CmdletBinding()]
Param (
[Parameter(Mandatory=$True, ValueFromPipeline=$True, HelpMessage="Enter an email address to compute hash")]
[ValidateScript({If ($_ -match "\b[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}\b") {$True}
Else {Throw "The email address $_ is not a valid email address format."}})]
[String[]]$Email
)

This would now return the error exception message:

The email address someone@where is not a valid email address format.

So, lets now look at computing the hash value for the string provided as a valid email address. By default, Windows PowerShell only provides the Get-FileHash cmdlet to compute the hash value for a file by using a specified hash algorithm.

In the initial instance I used the MD5 hash algorithm by creating a StringBuilder Class .NET Framework object  and invoking the HashAlgorithm Class to compute the hash value.


Begin {} #Begin
Process
{
Write-Verbose ("The following email addresses have been specified " + ($Email -join ',') + ".")
ForEach ($String in $Email)
{
Write-Verbose ("Computing hash for the email address " + $String+ ".")
$StringBuilder = New-Object System.Text.StringBuilder
[System.Security.Cryptography.HashAlgorithm]::Create("MD5").ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String))| ForEach-Object {
[Void]$StringBuilder.Append($_.ToString("x2"))} # ForEach-Object
return $StringBuilder.ToString()
} # ForEach
} #Process
End {} #End

This would return the following output when computing the hash algorithm:

CreateEmailHashMD5

Now we are all aware that MD5 contains weaknesses and we should not be using this as hashing algothrim for sensitive information so I will look at using alternative hashing algorithms and the Blowfish-based hashing algorithm (one good thing they were doing at Ashley Madison!) in additional posts covering this topic.

 


One thought on “Part One – Computing email address hash value using Windows PowerShell

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 )

Facebook photo

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

Connecting to %s