{"id":5,"date":"2016-02-01T01:37:34","date_gmt":"2016-02-01T01:37:34","guid":{"rendered":"http:\/\/www.timmevans.net\/blog\/?p=5"},"modified":"2016-10-10T18:33:29","modified_gmt":"2016-10-11T01:33:29","slug":"using-the-net-rngcryptoserviceprovider-in-powershell","status":"publish","type":"post","link":"https:\/\/www.timmevans.net\/blog\/using-the-net-rngcryptoserviceprovider-in-powershell\/","title":{"rendered":"Using the .Net RNGCryptoServiceProvider in Powershell"},"content":{"rendered":"<p>I was working on a password generator function, and I wanted to use something that was a better random number generator than Powershell\u2019s Get-Random cmdlet. I\u2019m not a crypto expert, so I\u2019ll leave the discussions about how good each random number generator is, but Matt Graeber wrote a <a href=\"http:\/\/www.powershellmagazine.com\/2014\/07\/28\/testing-the-effectiveness-of-get-random\/\" target=\"_blank\">nice article<\/a> that discusses how to test the effectiveness of a random number generator. According to Matt\u2019s testing, the RNGCryptoServiceProvider class is a better random number generator that Powershell\u2019s Get-Random for cryptographic purposes. I liked the way Get-Random worked, so I decided to implement a function that worked in a similar manner. Note, Get-Random works two ways: it either returns a random number or returns a random object from a collection of objects. This implementation only returns a random number.<\/p>\n<p>RNGCryptoServiceProvider implements a GetType method that is passed an array of bytes and returns it filled with random byte values. The trick here is, that I want to return a single unsigned 32 bit integer but GetType returns an array of bytes. I need to use the System.BitConverter .NET class to convert an array of bytes to a single uint32 value. The other challenge I ran into is how to implement minimum and maximum values. I decided to use the mod operator to return a value in the range I need.<\/p>\n<p>Here is the function I came up with:<\/p>\n<pre>Function Get-RandomInt {\r\n\u00a0\u00a0\u00a0 [cmdletbinding()]\r\n\u00a0\u00a0\u00a0 Param(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 [uint32]$max=[UInt32]::MaxValue,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 [uint32]$min=[UInt32]::MinValue\r\n\u00a0\u00a0\u00a0 )\r\n\u00a0\u00a0\u00a0 if ($min -lt $max) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 #initialize everything\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $diff=$max-$min+1\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 [Byte[]] $bytes = 1..4\u00a0 #4 byte array for int32\/uint32\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 #generate the number\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $rng.getbytes($bytes)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $number = [System.BitConverter]::ToUInt32(($bytes),0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $number = $number % $diff + $min\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return $number\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Write-Warning 'Min must be less than Max'\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return -1\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<p>Use it like this:<\/p>\n<pre>Get-RandomInt -min 1 -max 100<\/pre>\n<p>to get a random number between 1 and 100.<\/p>\n<p>&nbsp;<\/p>\n<p>&#8230;Tim<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was working on a password generator function, and I wanted to use something that was a better random number generator than Powershell\u2019s Get-Random cmdlet. I\u2019m not a crypto expert, so I\u2019ll leave the discussions about how good each random number generator is, but Matt Graeber wrote a nice article that discusses how to test [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-5","post","type-post","status-publish","format-standard","hentry","category-powershell"],"_links":{"self":[{"href":"https:\/\/www.timmevans.net\/blog\/wp-json\/wp\/v2\/posts\/5","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.timmevans.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.timmevans.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.timmevans.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.timmevans.net\/blog\/wp-json\/wp\/v2\/comments?post=5"}],"version-history":[{"count":6,"href":"https:\/\/www.timmevans.net\/blog\/wp-json\/wp\/v2\/posts\/5\/revisions"}],"predecessor-version":[{"id":31,"href":"https:\/\/www.timmevans.net\/blog\/wp-json\/wp\/v2\/posts\/5\/revisions\/31"}],"wp:attachment":[{"href":"https:\/\/www.timmevans.net\/blog\/wp-json\/wp\/v2\/media?parent=5"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.timmevans.net\/blog\/wp-json\/wp\/v2\/categories?post=5"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.timmevans.net\/blog\/wp-json\/wp\/v2\/tags?post=5"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}