Я пытаюсь использовать библиотеки .net для bouncy castle для обмена ключами Диффи-Хеллмана и столкнулся с проблемой при создании объекта DHParams.
Мое решение будет включать центральный орган, который будет генерировать отдельный ключ / пару DH для каждого подключаемого клиента. Идея заключается в том, что я буду хранить отдельное соглашение о ключе DH для каждого подключенного клиента. Затем я отправлю значение p, g клиенту, где клиент рассчитает его соответствие ключу dh. Я хочу генерировать разные значения p, g для каждого клиента. Я использую BigInteger для этого, но сталкиваюсь с некоторыми проблемами.
Когда я пытаюсь создать новый объект DHParameters, он выдает следующее исключение, когда я использую битовую длину, отличную от 768:
System.ArgumentException was unhandled
Message="generator must in the range [2, p - 2]\r\nParameter name: g"
Source="BouncyCastle.Crypto"
ParamName="g"
StackTrace:
at Org.BouncyCastle.Crypto.Parameters.DHParameters..ctor(BigInteger p, BigInteger g, BigInteger q, Int32 m, Int32 l, BigInteger j, DHValidationParameters validation)
at Org.BouncyCastle.Crypto.Parameters.DHParameters..ctor(BigInteger p, BigInteger g, BigInteger q, Int32 l)
at TestDH.Program.Main(String[] args) in C:\dev\source\TestDH\TestDH\Program.cs:line 30
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
"generator must in the range [2, p - 2]"
Я не уверен, имеет ли это значение, но я попробовал все виды различных значений для определенности в конструкторе BigInteger.
Вот мой код:
SecureRandom sr = new SecureRandom();
// p,g generation, done by central authority
BigInteger g512 = new BigInteger(512, 30, sr);
BigInteger p512 = new BigInteger(512, 30, sr);
// p,g is then sent to client from central authority
// common - performed by both server and client sides
IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("DH");
DHParameters dhParams = new DHParameters(p512, g512, null, 512); // Here is where I get the exception if the first parameter if BigInteger is not 768 or lager
Проблема заключается в том, что генерация 768-битного простого числа занимает слишком много времени - свыше 5 секунд на двухъядерном процессоре 2,1 ГГц без запуска других процессов. Это слишком большой штраф для каждого клиента, который инициирует соединение. Я хотел бы использовать меньшую длину в битах для BigInteger.
Я, вероятно, делаю это совершенно неправильно - есть скудная документация о том, как сделать DH с надувным замком, и тесты / примеры просто не соответствуют моему случаю использования. Я не хочу иметь предварительно сгенерированные значения p, g.
EDIT
Кажется, что даже длина 768 бит дает ошибки время от времени. После перезапуска моей машины я мог работать без разрядов, кроме 1024, и даже тогда только в 80% случаев. Я думаю, что я делаю что-то не так.