Return to HomePage



Generating Cryptographically Secure Random Numbers (VB)


Applies to

* .NET Framework 2.0
* VB

Summary

The purpose of this code snippet is to illustrate how to generate cryptographically secure random numbers for a variety of applications using .NET. Possible uses of cryptographically-secure random numbers are session identifiers, encryption key material and default or auto-generated passwords.

Objectives

* Create a random number value whose value cannot be utilized to determine subsequent number values generated by the same function


Scenarios

* Create an "un-guessable" session identifier or application cookie for customized session management
* Create a one-time-use number for use as a second authentication factor, such as an argument for use within a forgotten email password
* Create an arbitrary default secret, such as a default password, from random data


Solution Example

Function SecureRandomNumber() As Integer
		    		' Create a secure RNG class and a byte array to hold the random data
		    		Dim secureRandom As New [RNGCryptoServiceProvider()]
		    		Dim randBytes(4) As Byte
	

		    		' Generate 4 bytes of secure random number data and convert to 4-byte integer
		    		[secureRandom.GetNonZeroBytes(randBytes)]
		    		Return [BitConverter.ToInt32(randBytes,] 0)
	
End Function


Problem Example

The following example shows generation of a random number using the
System.Random class.

Function UnsecureRandomNumber(ByVal seed As Integer) As Integer
		    		' Creates a random number, using the default machine time-derived seed 
		    		Dim unsecureRandom As New Random(seed)
		    		Return unsecureRandom.Next()
	
End Function

* Same seed value will always return the same sequence of numbers
* Seed value -1 or null will make use of machine time to generate seed, which is easily predicted


Test Case

The following classes must be included in any project making use of the sample code provided above:

Imports System.Security.Cryptography

Run the following code to generate a set of both unsecure and secure random numbers. The unsecure example illustrates that two calls to Random that make use of the same seed will return the same sequence of numbers.

Sub Main(ByVal args() As String)
		    		' Unsecure Random Number
		    		Console.WriteLine(("Unsecure Value, Default Seed: " + [Convert.ToString(UnsecureRandomNumber(-1))))]
		    		Console.WriteLine(("Unsecure Value, Default Seed: " + [Convert.ToString(UnsecureRandomNumber(-1))))]
		    		Console.WriteLine(("Unsecure Value, Seed = 100: " + [Convert.ToString(UnsecureRandomNumber(100))))]
		    		Console.WriteLine(("Unsecure Value, Seed = 100: " + [Convert.ToString(UnsecureRandomNumber(100))))]
		    		Console.WriteLine("")
	

		    		' Secure Random Numbers
		    		Dim i As Integer
		    		For i = 0 To 9
		        			Console.WriteLine(("Secure Value, no seed: " + [Convert.ToString(SecureRandomNumber())))]
		    		Next i
	
End Sub 'Main

Function UnsecureRandomNumber(ByVal seed As Integer) As Integer
		    		' Creates a random number, using the default machine time-derived seed 
		    		Dim unsecureRandom As New Random(seed)
		    		Return unsecureRandom.Next()
	
End Function


Expected Result

Unsecure Value, Default Seed: 534011718
Unsecure Value, Default Seed: 534011718
Unsecure Value, Seed = 100: 2080427802
Unsecure Value, Seed = 100: 2080427802

Secure Value, no seed: 1392122031
Secure Value, no seed: -1635401565
Secure Value, no seed: 1863340408
Secure Value, no seed: -497957136
Secure Value, no seed: -1444637226
Secure Value, no seed: 925340612
Secure Value, no seed: 92412438
Secure Value, no seed: -1126434204
Secure Value, no seed: 2086044763
Secure Value, no seed: -840759923



Additional Resources

* Generating Random Keys (.NET): http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGGuidelines0003.asp?frame=true#pagguidelines0003_crypto3
* RNGCryptoServiceProvider Class: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemsecuritycryptographyrngcryptoserviceproviderclasstopic.asp

Attributes

* Applies To: .NET Framework 2.0, VB
* Category: Cryptography
* Author: Jonathan Bailey



Return to HomePage
Microsoft Communities