Надувной замок Diffie-Hellman DHParams Issue - PullRequest
0 голосов
/ 02 февраля 2012

Я пытаюсь использовать библиотеки .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% случаев. Я думаю, что я делаю что-то не так.

1 Ответ

3 голосов
/ 02 февраля 2012

Я понял это. Вы не должны использовать конструктор для DHParameters. Используйте утилиту генератора для получения ваших параметров. Вот код, который работает:

        const int DefaultPrimeProbability = 30;

        DHParametersGenerator generator = new DHParametersGenerator();
        generator.Init(512, DefaultPrimeProbability, new SecureRandom());
        DHParameters parameters = generator.GenerateParameters();

        KeyGenerationParameters kgp = new DHKeyGenerationParameters(new SecureRandom(), parameters);
        keyGen.Init(kgp);

        AsymmetricCipherKeyPair aliceKeyPair = keyGen.GenerateKeyPair();
        IBasicAgreement aliceKeyAgree = AgreementUtilities.GetBasicAgreement("DH");
        aliceKeyAgree.Init(aliceKeyPair.Private);

        AsymmetricCipherKeyPair bobKeyPair = keyGen.GenerateKeyPair();
        IBasicAgreement bobKeyAgree = AgreementUtilities.GetBasicAgreement("DH");
        bobKeyAgree.Init(bobKeyPair.Private);

        BigInteger aliceAgree = aliceKeyAgree.CalculateAgreement(bobKeyPair.Public);
        BigInteger bobAgree = bobKeyAgree.CalculateAgreement(aliceKeyPair.Public);

        if (!aliceAgree.Equals(bobAgree))
        {
            throw new Exception("Keys do not match.");
        }

        // generate key from prime integers generated above
...