0

我正在尝试使用 bouncy castle .net 库来执行 Diffie-Hellman 密钥交换,并且在生成 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 位素数需要很长时间——在没有其他进程运行的双核 2.1Ghz 处理器上超过 5 秒。对于每个启动连接的客户端来说,这实在是太大了。我想为 BigInteger 使用较小的位长度。

我可能完全错了 - 关于如何使用充气城堡进行 DH 的文档很少,而且测试/示例与我的用例不匹配。我不想有预先生成的 p,g 值。

编辑 似乎即使是 768 位长度也会偶尔出现错误。重新启动我的机器后,除了 1024 之外,我无法获得任何位长度,即使如此,也只有大约 80% 的时间。我想我做错了什么。

4

1 回答 1

3

我想到了。您不应该使用 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
于 2012-02-02T00:44:53.530 回答