0

I am communicating with a device that uses AES-CCM encryption and I need to set that up using a key derived by ECDH. My machine cert has an ECC private key in the TPM.

I'm somewhat new to this so please bear with me.

Here's the code I'm looking at now. Is this the correct way to sign the key with my certificate?

//this will actually be loaded by another method.  Only here for demo purposes;
X509Certificate2 masterEndEntityCert;

//we are using the NST p-256 curve
using (var ecdh = new ECDiffieHellmanCng(ECCurve.NamedCurves.nistP256))
{
    //our HKDF should be HMAC
    ecdh.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hmac;
    ecdh.HashAlgorithm = CngAlgorithm.Sha256;

    //get the ephemeral key to send to the other device
    var ephemeralKey = ecdh.PublicKey.ToByteArray();

    //get the ecdsa private key from my cert for signing
    using (var alg = masterEndEntityCert.GetECDsaPrivateKey() as ECDsaCng)
    {
        //sign the sha256 hash of the key
        var sig = alg.SignData(ephemeralKey, HashAlgorithmName.SHA256);

        //concat the ephemeral key and the signed hash together for transmission
        this.SignedEphemeralPublicKey = ephemeralKey.Concat(sig).ToArray();
    }
}
Sam
  • 1,325
  • 1
  • 13
  • 26
  • 1
    I don't see anything wrong. However, if it is correct or not depends on the protocol you are implementing. The `byte[]` encoding of the public key returned by `ToByteArray()` in unspecified in .NET it seems. Those kind of things you would expect to be in a protocol description, which is missing too often for crypto code. You may want to put more data in the signature than just the DH public key and / or check the data send using HMAC after key agreement. – Maarten Bodewes Mar 05 '19 at 00:06
  • PS, I can only owl with you, [the bear](https://stackoverflow.com/users/254279) doesn't often visit SO anymore. – Maarten Bodewes Mar 05 '19 at 00:07
  • @MaartenBodewes Thanks for the reply. The firmware specs for the device requires that the exchange contain only the public key and the signature of the key hash. – Sam Mar 05 '19 at 02:11
  • 1
    Make sure you've got the right format of the key in that case. You can post it in base64 here so I can see what it is, if you @MaartenBodewes me. – Maarten Bodewes Mar 05 '19 at 02:39
  • @MaartenBodewes I went back over the spec and actually, I'm not using ToArray() as I'm only supposed to send the x coordinate concatenated with the y coordinate. Calling ToArray() dumps out the key in a blob format with a header. – Sam Mar 05 '19 at 04:02
  • 1
    In that case you want to read [this answer](https://crypto.stackexchange.com/a/37544/1172) about I2OSP to perform the conversion correctly. Beware that X and Y may be any value up to the field size and may include initial zero bytes for a *signed* representation. – Maarten Bodewes Mar 05 '19 at 11:01
  • @MaartenBodewes I'm not sure I follow. The device is expecting the raw bytes so I don't know if there is any conversion needed? – Sam Mar 05 '19 at 16:37
  • 1
    If you can get to the raw bytes then you're OK, generally however you need to convert from a signed integer to a statically sized, big endian, unsigned integer. If that's what you have or can extract - e.g. within an uncompressed point - then you're golden. – Maarten Bodewes Mar 05 '19 at 22:43

0 Answers0