C# 如何使用给定两个密钥的BouncyCastle获取共享秘密?

C# 如何使用给定两个密钥的BouncyCastle获取共享秘密?,c#,bouncycastle,C#,Bouncycastle,需要在给定的64字节公钥(他们的)和32字节私钥(我们的)之间共享秘密 我拥有由外部提供商生成的密钥(p-256 ECC代码)。公钥为64字节,私钥为32字节 我不知道如何让BouncyCastle导入这些关键点。它似乎期望DER编码的密钥,但这不是我必须处理的 public static byte[] GetSharedSecret(byte[] their_public, byte[] our_private) { // their_public: 64 byte public key

需要在给定的64字节公钥(他们的)和32字节私钥(我们的)之间共享秘密

我拥有由外部提供商生成的密钥(p-256 ECC代码)。公钥为64字节,私钥为32字节

我不知道如何让BouncyCastle导入这些关键点。它似乎期望DER编码的密钥,但这不是我必须处理的

public static byte[] GetSharedSecret(byte[] their_public, byte[] our_private)
{
  // their_public: 64 byte public key
  // our_private: 32 byte private key
  var pri = PrivateKeyFactory.CreateKey(our_private); // this fails
  var pub = PublicKeyFactory.CreateKey(their_public); // this fails

  // Expected to produce a 32 byte shared secret:
  return ??SomeBouncyCastleCode??.GetSharedSecret();
}
我的期望是,加密/密钥代码使用32和64字节的密钥数组。在处理嵌入式设备和代码空间有限的其他领域时,处理包装的/DER/xyz编码密钥是不奢侈的。这些都被剥离到实际的键值,这就是我要处理的全部内容

public static byte[] GetSharedSecret(byte[] their_public, byte[] our_private)
{
  // their_public: 64 byte public key
  // our_private: 32 byte private key
  var pri = PrivateKeyFactory.CreateKey(our_private); // this fails
  var pub = PublicKeyFactory.CreateKey(their_public); // this fails

  // Expected to produce a 32 byte shared secret:
  return ??SomeBouncyCastleCode??.GetSharedSecret();
}

我不知道如何使用BouncyCastle实现此功能。

AgreementUtilities.GetBasicAgreement
返回
IBasicAgreement
,您可以
Init
私钥和
CalculateAgreement
。计算结果是一个
BigInteger

要解析键,可以使用
Curve.DecodePoint

下面是一个例子:

var ecP = ECNamedCurveTable.GetByName("curveNameHere");
var ecSpec = new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed());
var publicKey = new ECPublicKeyParameters(ecSpec.Curve.DecodePoint(YourByteArray), ecSpec);

IBasicAgreement agreement = AgreementUtilities.GetBasicAgreement("nameHere");
agreement.Init(privateKey);
BigInteger result = agreement.CalculateAgreement(publicKey);
return result.ToByteArrayUnsigned();

这个答案的问题是,它假设
privateKey
是一个CipherParameters对象,但OPs私钥只有32个字节。所以这对他不起作用。@SGKoishi对BouncyCastle名称空间的彻底搜索不会产生任何名为ECNamedCurveTable的方法/类,也不会产生您列出的其他方法/类。我在任何地方都找不到这些(AgreementUtilities除外,我可以访问它)。我使用NuGet包Portable.boungycastl-Signed,我们需要它来瞄准移动设备和其他物联网设备。@ts90你说得对。我使用的是BouncyCastle的默认版本,它有
Org.BouncyCastle.Asn1.X9.ECNamedCurveTable
()和其他方法。您可能会从这个版本中找到一些有用的代码,但我不确定是否有更好的方法可以做到这一点。您的密钥是字节数组,因此是实际ECC参数的编码形式。我们只能猜测这种编码是什么。我的猜测是:公钥是代表点(x,y)坐标的两个32字节大端整数的编码,私钥是另一个大端整数。@JamesKPolk-我不知道这是否有帮助,但如果我使用BCRYPT_ECDH_public_P256_MAGIC=0x314B4345手动编码密钥,我能够将有效(且可用)的CngKey(CngKeyBlobFormat.EccPublicBlob)导入到微软的加密技术中。尽管如此,这并不能解决我的问题,因为我需要可移植的弹性城堡解决方案。