Generating cryptographically secure random numbers with PowerShell

Recently I’ve found myself writing some code which heavily leverages the cryptography libraries defined in .Net.

During this project, for testing purposes, I wanted to generate a file of cryptographically strong random bytes – but I wanted to use PowerShell because I find it is much faster to prototype with. So, how does one do this?

Well, you mind say “I think I’ll use Get-Random!” and I might then say “Think Again!”. Why? Because the Get-Random cmdlet does not produce crypto-secure randoms. Get-Random actually uses System.Random class which has the following to say:

Pseudo-random numbers are chosen with equal probability from a finite set of numbers. The chosen numbers are not completely random because a mathematical algorithm is used to select them, but they are sufficiently random for practical purposes. The current implementation of the Randomclass is based on a modified version of Donald E. Knuth’s subtractive random number generator algorithm. For more information, see D. E. Knuth. The Art of Computer Programming, Volume 2: Seminumerical Algorithms. Addison-Wesley, Reading, MA, third edition, 1997.

To generate a cryptographically secure random number, such as one that’s suitable for creating a random password, use theRNGCryptoServiceProvider class or derive a class from System.Security.Cryptography.RandomNumberGenerator.

Ref: https://msdn.microsoft.com/en-us/library/system.random(v=vs.110).aspx

So, let’s say I want to generate a file that is 256 bytes of cryptographically strong randoms. Well, here is one solution to do achieve this:


$prng = [System.Security.Cryptography.RNGCryptoServiceProvider]::Create()

[byte[]] $randomBytes = @(0) * 256
$prng.GetBytes($randomBytes)

[System.IO.File]::WriteAllBytes("C:\securefile.dat", $randomBytes)

Let’s break this down.

1. Instantiate an instance of Microsoft’s Cryptographically Strong Psuedo Random Number Generator (“prng”)

3. Create a byte array of 256 elements. Yes, this is kind of an ugly way to instantiate a byte array but, hey – it’s powershell- what can I tell you? This (as yet) empty byte array is where we’re going to store our random bytes in a second.

4. Now we pass the byte array as a parameter to the GetBytes method provided by the PRNG object we instantiated in line 1. I know that mostly you assign values like “x = 1+2” but in the case of arrays, we’re really passing a pointer to the array so the method can manipulate it directly. When line 4 is done executing, the randomBytes byte array that we declared in line 3 will be full of random bytes.

6. Finally – we use .Net’s System.IO.File’s static method called “WriteAllBytes” to write our newly generated random bytes to a file. This method takes two parameters, first – a file name, and second – an array of bytes.

Now we have a file that should be indistinguishable from random and is an excellent choice for security related work.

Hope this helps!
Sam

 

Advertisements

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 )

Google+ photo

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

Connecting to %s