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