Bouncy Castle Diffie-Hellman DHParams问题

时间:2012-02-01 20:34:37

标签: .net cryptography bouncycastle diffie-hellman

我正在尝试使用充气城堡.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%的时间。我想我做错了。

1 个答案:

答案 0 :(得分: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