using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace KFDtool.P25.Generator { public class KeyGenerator { // internal method from .NET 4.8 refsrc system\security\cryptography\utils.cs FixupKeyParity() private static byte[] FixupKeyParity(byte[] key) { byte[] oddParityKey = new byte[key.Length]; for (int index = 0; index < key.Length; index++) { // Get the bits we are interested in oddParityKey[index] = (byte)(key[index] & 0xfe); // Get the parity of the sum of the previous bits byte tmp1 = (byte)((oddParityKey[index] & 0xF) ^ (oddParityKey[index] >> 4)); byte tmp2 = (byte)((tmp1 & 0x3) ^ (tmp1 >> 2)); byte sumBitsMod2 = (byte)((tmp2 & 0x1) ^ (tmp2 >> 1)); // We need to set the last bit in oddParityKey[index] to the negation // of the last bit in sumBitsMod2 if (sumBitsMod2 == 0) oddParityKey[index] |= 1; } return oddParityKey; } public static List GenerateVarKey(int keyLenBytes) { if (keyLenBytes < 1) { throw new ArgumentOutOfRangeException(); } RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); byte[] key = new byte[keyLenBytes]; rngCsp.GetBytes(key); List key2 = new List(); key2.AddRange(key); rngCsp.Dispose(); return key2; } public static List GenerateSingleDesKey() { // DESCryptoServiceProvider.GenerateKey() does NOT create a DES key with the correct parity // https://social.msdn.microsoft.com/Forums/vstudio/en-US/8439cc0b-486b-4083-a35e-eeef3571b064/des-generated-key-incorrect-parity?forum=clr byte[] key = GenerateVarKey(8).ToArray(); return FixupKeyParity(key).ToList(); } } }