More Fun with Passwords
Given the sad frequency with which web sites get their password stores leaked, using the same password, N0M@tt3rH0w5tr0ng!!! is a very bad idea. Recent articles have shown how even hashed password strings can get translated back to their plaintext counterparts.
Enter password utilities. These programs store your passwords for you. This means you can (and should) use a separate password for each site. They run locally, so even if your favourite web site gets cracked and your password reverted, the attacker gains access to only that site.
This post is useful only as a learning exercise for how to code something similar to those programs. It can also be used in case you need to programmatically generate passwords by the dozens, and want your users to hate you while doing so. (Insert smiley here.)
function Export-Password {
param ( [string]$Password );
Add-Type -AssemblyName System.Security;
[Convert]::ToBase64String([System.Security.Cryptography.ProtectedData]::Protect([System.Text.Encoding]::Unicode.GetBytes($Password), $null, 'CurrentUser'));
}
function Import-Password {
param ( [string]$HashString );
Add-Type -AssemblyName System.Security;
[System.Text.Encoding]::Unicode.GetString([System.Security.Cryptography.ProtectedData]::Unprotect([Convert]::FromBase64String($HashString), $null, 'CurrentUser'));
}
function New-Password {
param (
[int]$Length = 16,
[int]$MinNonAlpha = 4
);
Add-Type -AssemblyName System.Web;
$pass = [System.Web.Security.Membership]::GeneratePassword($Length, $MinNonAlpha);
if ($MinNonAlpha) {
$pass;
} else {
(1..$Length) | % { $pass += [System.Web.Security.Membership]::GeneratePassword($Length, $MinNonAlpha); }
($pass -replace '[^A-Za-z0-9]').SubString(0,$Length);
}
}
A few words about the functions.
Import-Password: It and Export-Password generate salted hash strings in the ‘Current'User’ scope. Only the user who created the hash can revert it.
New-Password: Some sites forbid the use of special characters and require their passwords be only alphanumeric characters. While this is not a good idea, getting the site to change their password policies may entail a back-end change as well, and is beyond the scope of this post. Here, I’m just explaining how setting –MinNonAlpha to 0 will cause the function to generate an alphanumeric-only password by RegExing the non-alphanumeric characters out., then taking a SubString() of what is left.