The usage of random numbers is often critically important for the security of cryptography-focused applications. With this, the random oracle model defines that the security of the overall method is defined by the randomness of the oracle value that we use. The code used to create these programs must thus be free of flaws and often have to comply with the Federal Information Processing Standard (FIPS) standard. In this case, we will use the Bouncy Castle FIPS (FIPS) C# API. This needs the bc-fips-1.0.2.dll assembly and which integrates into the System.Security.Cryptography provider.
FIPS Random Number Generaetion in C# |
Coding
First we create a folder named "bc_fips01", and then go into that folder.We can create a Dotnet console project for .NET 8.0 with:
dotnet new console --framework net8.0
Next we download the FIPS module (bc-fips-1.0.2.dll) from [here] and add it as a reference to the project:
This produces a Csproject file of:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <Reference Include="Org.BouncyCastle.Crypto"> <HintPath>bc-fips-1.0.2.dll</HintPath> </Reference> </ItemGroup> </Project>
The coding is:
namespace ECC { using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Fips; using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Security; class Program { static void Main(string[] args) { string size="32"; if (args.Length >0) size=args[0]; try { var entSource = new BasicEntropySourceProvider (new SecureRandom(), true); IDrbgBuildertheDrbgBuilder = CryptoServicesRegistrar.CreateService(FipsDrbg.Sha512HMac).FromEntropySource(entSource); theDrbgBuilder.SetSecurityStrength(256); theDrbgBuilder.SetEntropyBitsRequired(256); theDrbgBuilder.SetPersonalizationString(System.Text.Encoding.ASCII.GetBytes("The cat on the mat")); byte[] nonce = new byte[Convert.ToInt16(size)]; var n=theDrbgBuilder.Build(nonce,false); Console.WriteLine("Size: {0}",size); Console.WriteLine("Random Seed: {0}",Convert.ToHexString(n.GenerateSeed(Convert.ToInt16(size)))); Console.WriteLine("Hash Code: {0}",(n.GetHashCode())); for (int i=0;i<5;i++) { Console.WriteLine("Random Int64: {0}",n.NextInt64()); } for (int i=0;i<5;i++) { n.NextBytes(nonce); Console.WriteLine("Random Hex {0}",Convert.ToHexString(nonce)); } for (int i=0;i<5;i++) { Console.WriteLine("Random Double {0}",n.NextDouble()); } } catch (Exception e) { Console.WriteLine("Error: {0}",e.Message); } } } }
A sample run is:
Size: 16 Random Seed: 77C2DDA2ED570FBA03CFA16824192698 Hash Code: 58225482 Random Int64: 2185014096620394652 Random Int64: 6547259502637679065 Random Int64: 6081615623724165065 Random Int64: 8531401192076663666 Random Int64: 8149660133904283657 Random Hex 5C667296AF1F89EE2488DCD583C31742 Random Hex 98D05CE2A4D68D981A6117A29C432302 Random Hex D2CAD8C50D15562E8C32B5353CCEA90E Random Hex A1EFAAE9BAC9E8F947CD9093CF5F48D5 Random Hex A00B41BECCD445C9E1006DE280A0FE75 Random Double 0.9227581456101644 Random Double 0.7963939883459085 Random Double 0.6233004414069624 Random Double 0.11342376685574285 Random Double 0.303790433615841