CMACs (Cipher-based message authentication codes) create a message authentication codes (MACs) using a block cipher and a secret key. They differ from HMACs in that they use a symmetric key method for the MACs rather than a hashing method. When the receipient receives the CMAC field, they will aslo compute the same CMAC with the message and the secrete key. If they are the same, the receipient knows that the message has not been changed, and signed with the secret key.
FIPS CMAC using Bouncy Castle and C# |
Code
First we create a folder named "bc_fips_mac", 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>
Next some code:
namespace CMAC { using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Fips; using Org.BouncyCastle.Security; using System.Text.Json; class Program { static void Main(string[] args) { var keystr="0000000000000000000000000000000000000000000000000000000000000000"; var msg="Hello 123"; var size=64; if (args.Length >0) msg=args[0]; if (args.Length >1) size=Convert.ToInt32(args[1]); var message=System.Text.Encoding.ASCII.GetBytes(msg); var key=System.Convert.FromHexString(keystr); try { var calcFact = CryptoServicesRegistrar.CreateService(new FipsAes.Key(FipsAes.CMac, key)) .CreateMacFactory(FipsAes.CMac.WithMacSize(size)); IStreamCalculator <IBlockResult> macCalculator = calcFact.CreateCalculator(); Stream macStream = macCalculator.Stream; macStream.Write(message, 0, message.Length); macStream.Close(); var mac= macCalculator.GetResult().Collect(); Console.WriteLine("Message: {0}",msg); Console.WriteLine("Key: {0}",keystr); Console.WriteLine("CMAC: {0}",Convert.ToHexString(mac)); Console.WriteLine("CMAC: {0}",Convert.ToBase64String(mac)); } catch (Exception e) { Console.WriteLine("Error: {0}",e.Message); } } } }
A sample run gives:
Message: Hello 123 Key: 0000000000000000000000000000000000000000000000000000000000000000 CMAC: 025A2541A6DAE5C82A848C4A4715BA5E