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.
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!