Search code examples
c#bouncycastlepublic-keyelliptic-curvediffie-hellman

AsymmetricKeyParameter as byte[]


I'm trying to do an ECDH key exchange using C# BouncyCastle. I have been successful in creating the necessary AsymmetricCipherKeyPair objects and I'm also able to generate the shared key of the other partys public key.

However, to actually exchange the public key, I need it as a byte[] or at least anything I can turn into raw data, since the protocol I'm using to transport the keys between the parties wont take any BouncyCastle object.

   X9ECParameters ecPars = NistNamedCurves.GetByName("P-521");
  ECDomainParameters ecDomPars = new ECDomainParameters(ecPars.Curve, ecPars.G, ecPars.N, ecPars.H, ecPars.GetSeed());
  IAsymmetricCipherKeyPairGenerator gen = GeneratorUtilities.GetKeyPairGenerator("ECDH");
  gen.Init(new ECKeyGenerationParameters(ecDomPars, new SecureRandom()));

  AsymmetricCipherKeyPair keyPair = gen.GenerateKeyPair();
  IBasicAgreement keyAgreement = AgreementUtilities.GetBasicAgreement("ECDH");
  keyAgreement.Init(keyPair.Private);

So what I'm needing here is the key value of keyPair.Public as a byte[].

I hope you understand where I'm heading and can help me.


Solution

  • If you have only an ECPublicKeyParameter 'pub' (i.e. from keyPair.Public), you can get the public point encoding:

    byte[] data = pub.Q.GetEncoded();
    

    At the receiving end:

    ECCurve curve = ecDomPars.Curve;
    ECPoint q = curve.DecodePoint(data);
    ECPublicKeyParameter peerPub = new ECPublicKeyParameter(q, ecDomPars);
    

    It's more typical to exchange certificates, or else you will have no assurance of whom you're "agreeing" with.

    I'm a bit concerned that you might be "rolling your own crypto protocol"; if this is for a real application, please consider using an existing protocol, maybe just TLS.