KFDtool/sw/control/KFDtool.P25/Generator/KeyGenerator.cs

56 lines
2.2 KiB
C#
Raw Normal View History

2019-07-29 15:24:10 -06:00
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<byte> GenerateVarKey(int keyLenBytes)
{
if (keyLenBytes < 1)
{
throw new ArgumentOutOfRangeException();
}
RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
byte[] key = new byte[keyLenBytes];
rngCsp.GetBytes(key);
List<byte> key2 = new List<byte>();
key2.AddRange(key);
rngCsp.Dispose();
return key2;
}
public static List<byte> 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();
}
}
}