如何在 C# 中使用 BouncyCastle 的 Diffie-Hellman?
How to use BouncyCastle's Diffie-Hellman in C#?
我正在编写一个可以在 phone 和 Windows PC 之间交换数据的应用程序,我想保护使用 Diffie-Hellman 交换生成的密钥发送的数据。
我正尝试为此使用 BouncyCastle,但几乎不存在的 C# 实现文档让我感到困惑。
我想知道的是:收到对方密钥后,生成DH密钥并计算共享密钥的流程是怎样的? (我假设我可以将我的密钥作为字符串发送,并且我可以将另一方的密钥作为字符串使用。)我在 C# 中使用什么 objects/methods?
好吧,经过大量的尝试,我成功了。发布答案以防其他人需要它。
我假设 reader (1) 知道 Diffie-Hellman 是什么以及它的用途(阅读 here 了解详细信息)和 (2) 已经将 Bouncycastle 导入到 .NET通过 NuGet 项目。
您需要的进口商品:
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
如何生成g和p:
public DHParameters GenerateParameters()
{
var generator = new DHParametersGenerator();
generator.Init(BitSize, DefaultPrimeProbability, new SecureRandom());
return generator.GenerateParameters();
}
想要将 g 和 p 作为字符串获取吗?
public string GetG(DHParameters parameters)
{
return parameters.G.ToString();
}
public string GetP(DHParameters parameters)
{
return parameters.P.ToString();
}
如何生成a和A:
public AsymmetricCipherKeyPair GenerateKeys(DHParameters parameters)
{
var keyGen = GeneratorUtilities.GetKeyPairGenerator("DH");
var kgp = new DHKeyGenerationParameters(new SecureRandom(), parameters);
keyGen.Init(kgp);
return keyGen.GenerateKeyPair();
}
想将 a 和 A 作为字符串读取吗?
// This returns A
public string GetPublicKey(AsymmetricCipherKeyPair keyPair)
{
var dhPublicKeyParameters = _generatedKey.Public as DHPublicKeyParameters;
if (dhPublicKeyParameters != null)
{
return dhPublicKeyParameters.Y.ToString();
}
throw new NullReferenceException("The key pair provided is not a valid DH keypair.");
}
// This returns a
public string GetPrivateKey(AsymmetricCipherKeyPair keyPair)
{
var dhPrivateKeyParameters = _generatedKey.Private as DHPrivateKeyParameters;
if (dhPrivateKeyParameters != null)
{
return dhPrivateKeyParameters.X.ToString();
}
throw new NullReferenceException("The key pair provided is not a valid DH keypair.");
}
要从字符串中导入参数,只需执行以下操作:
var importedParameters = new DHParameters(p, g);
要生成 b 和 B 只需使用 GenerateKeys()
和 importedParameters
而不是生成的 parameters
.
假设您生成了 b 和 B,并且已经得到了 p、g 和 A。要计算共享密钥:
public BigInteger ComputeSharedSecret(string A, AsymmetricKeyParameter bPrivateKey, DHParameters internalParameters)
{
var importedKey = new DHPublicKeyParameters(new BigInteger(A), internalParameters);
var internalKeyAgree = AgreementUtilities.GetBasicAgreement("DH");
internalKeyAgree.Init(bPrivateKey);
return internalKeyAgree.CalculateAgreement(importedKey);
}
对 A 重复,现在您拥有 2 个客户端之间的共享密钥,准备用于加密通信。
希望这有用。
基于 PEM 文件格式的 Diffie-Hellman 密钥协议的实现 BouncyCastle.Diffie-hellman
Example
// Public Key Alice
var pubAlice = @"-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOkLo3q6MN3XS5xlY3OowqMkvPrYz
j4hLVJ2Wkuob3KQb1QidaAQsJ6Azy0yTuBanL4iy+dewA3YjejBMZEoh6w==
-----END PUBLIC KEY-----
";
// EC-Private Key Alice
var priAlice = @"-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIC9LMxwIwKThjtaUAJbJBCU0vFa+H8G98p/Z9JLYmEehoAoGCCqGSM49
AwEHoUQDQgAEOkLo3q6MN3XS5xlY3OowqMkvPrYzj4hLVJ2Wkuob3KQb1QidaAQs
J6Azy0yTuBanL4iy+dewA3YjejBMZEoh6w==
-----END EC PRIVATE KEY-----
";
// Public Key Bob
var pubBob = @"-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEnDMGlBFH7jbHHAYgdPR7247xqzRF
Y1HFy4HfejSgUKBxgj6biZUwSbNKuino7ObZnqrnJayWJZ7f4Eb6XuT6yQ==
-----END PUBLIC KEY-----
";
// EC-Private Key Bob
var priBob = @"-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIGqA4f7o5oBF5FgEQtNmz6fWKg/OcPPUORMX3uRc7sduoAoGCCqGSM49
AwEHoUQDQgAEnDMGlBFH7jbHHAYgdPR7247xqzRFY1HFy4HfejSgUKBxgj6biZUw
SbNKuino7ObZnqrnJayWJZ7f4Eb6XuT6yQ==
-----END EC PRIVATE KEY-----
";
var secretAlice = DiffieHellmanKeyAgreementUtil.GetPairKey(priAlice, pubBob);
var secretBob = DiffieHellmanKeyAgreementUtil.GetPairKey(priBob, pubAlice);
Console.WriteLine($"secretAlice: {secretAlice}");
Console.WriteLine($"secretBob: {secretBob}");
输出
秘密爱丽丝:RGZcMLnsXJqbQ/JGIIl61l/XpIgSL43Ync+16YKyMuQ=
secretBob: RGZcMLnsXJqbQ/JGIIl61l/XpIgSL43Ync+16YKyMuQ=
我正在编写一个可以在 phone 和 Windows PC 之间交换数据的应用程序,我想保护使用 Diffie-Hellman 交换生成的密钥发送的数据。
我正尝试为此使用 BouncyCastle,但几乎不存在的 C# 实现文档让我感到困惑。
我想知道的是:收到对方密钥后,生成DH密钥并计算共享密钥的流程是怎样的? (我假设我可以将我的密钥作为字符串发送,并且我可以将另一方的密钥作为字符串使用。)我在 C# 中使用什么 objects/methods?
好吧,经过大量的尝试,我成功了。发布答案以防其他人需要它。
我假设 reader (1) 知道 Diffie-Hellman 是什么以及它的用途(阅读 here 了解详细信息)和 (2) 已经将 Bouncycastle 导入到 .NET通过 NuGet 项目。
您需要的进口商品:
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
如何生成g和p:
public DHParameters GenerateParameters()
{
var generator = new DHParametersGenerator();
generator.Init(BitSize, DefaultPrimeProbability, new SecureRandom());
return generator.GenerateParameters();
}
想要将 g 和 p 作为字符串获取吗?
public string GetG(DHParameters parameters)
{
return parameters.G.ToString();
}
public string GetP(DHParameters parameters)
{
return parameters.P.ToString();
}
如何生成a和A:
public AsymmetricCipherKeyPair GenerateKeys(DHParameters parameters)
{
var keyGen = GeneratorUtilities.GetKeyPairGenerator("DH");
var kgp = new DHKeyGenerationParameters(new SecureRandom(), parameters);
keyGen.Init(kgp);
return keyGen.GenerateKeyPair();
}
想将 a 和 A 作为字符串读取吗?
// This returns A
public string GetPublicKey(AsymmetricCipherKeyPair keyPair)
{
var dhPublicKeyParameters = _generatedKey.Public as DHPublicKeyParameters;
if (dhPublicKeyParameters != null)
{
return dhPublicKeyParameters.Y.ToString();
}
throw new NullReferenceException("The key pair provided is not a valid DH keypair.");
}
// This returns a
public string GetPrivateKey(AsymmetricCipherKeyPair keyPair)
{
var dhPrivateKeyParameters = _generatedKey.Private as DHPrivateKeyParameters;
if (dhPrivateKeyParameters != null)
{
return dhPrivateKeyParameters.X.ToString();
}
throw new NullReferenceException("The key pair provided is not a valid DH keypair.");
}
要从字符串中导入参数,只需执行以下操作:
var importedParameters = new DHParameters(p, g);
要生成 b 和 B 只需使用 GenerateKeys()
和 importedParameters
而不是生成的 parameters
.
假设您生成了 b 和 B,并且已经得到了 p、g 和 A。要计算共享密钥:
public BigInteger ComputeSharedSecret(string A, AsymmetricKeyParameter bPrivateKey, DHParameters internalParameters)
{
var importedKey = new DHPublicKeyParameters(new BigInteger(A), internalParameters);
var internalKeyAgree = AgreementUtilities.GetBasicAgreement("DH");
internalKeyAgree.Init(bPrivateKey);
return internalKeyAgree.CalculateAgreement(importedKey);
}
对 A 重复,现在您拥有 2 个客户端之间的共享密钥,准备用于加密通信。
希望这有用。
基于 PEM 文件格式的 Diffie-Hellman 密钥协议的实现 BouncyCastle.Diffie-hellman
Example
// Public Key Alice
var pubAlice = @"-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOkLo3q6MN3XS5xlY3OowqMkvPrYz
j4hLVJ2Wkuob3KQb1QidaAQsJ6Azy0yTuBanL4iy+dewA3YjejBMZEoh6w==
-----END PUBLIC KEY-----
";
// EC-Private Key Alice
var priAlice = @"-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIC9LMxwIwKThjtaUAJbJBCU0vFa+H8G98p/Z9JLYmEehoAoGCCqGSM49
AwEHoUQDQgAEOkLo3q6MN3XS5xlY3OowqMkvPrYzj4hLVJ2Wkuob3KQb1QidaAQs
J6Azy0yTuBanL4iy+dewA3YjejBMZEoh6w==
-----END EC PRIVATE KEY-----
";
// Public Key Bob
var pubBob = @"-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEnDMGlBFH7jbHHAYgdPR7247xqzRF
Y1HFy4HfejSgUKBxgj6biZUwSbNKuino7ObZnqrnJayWJZ7f4Eb6XuT6yQ==
-----END PUBLIC KEY-----
";
// EC-Private Key Bob
var priBob = @"-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIGqA4f7o5oBF5FgEQtNmz6fWKg/OcPPUORMX3uRc7sduoAoGCCqGSM49
AwEHoUQDQgAEnDMGlBFH7jbHHAYgdPR7247xqzRFY1HFy4HfejSgUKBxgj6biZUw
SbNKuino7ObZnqrnJayWJZ7f4Eb6XuT6yQ==
-----END EC PRIVATE KEY-----
";
var secretAlice = DiffieHellmanKeyAgreementUtil.GetPairKey(priAlice, pubBob);
var secretBob = DiffieHellmanKeyAgreementUtil.GetPairKey(priBob, pubAlice);
Console.WriteLine($"secretAlice: {secretAlice}");
Console.WriteLine($"secretBob: {secretBob}");
输出 秘密爱丽丝:RGZcMLnsXJqbQ/JGIIl61l/XpIgSL43Ync+16YKyMuQ= secretBob: RGZcMLnsXJqbQ/JGIIl61l/XpIgSL43Ync+16YKyMuQ=