ECDiffieHellman-mbedTLS vs C#

问题描述 投票:1回答:1

我需要在ARM cortex M3和PC之间使用椭圆曲线Diffie Hellman。在ARM上,我使用mbed TLS。在PC端,我要使用C#和ECDiffieHellman(Cng)类。

我可以在ARM vs ARM上执行ECDH,但是当我尝试用PC替换一侧时确实遇到了麻烦。

  1. 问题是关键交换。我发现,该密钥由mbed TLS导出为<LEN><0x04><X><Y>

因此,在C#中,我正在使用导入公钥

私有静态EC

DiffieHellmanPublicKey ToPublicKey(byte[] publicKey)
{
    var keyLength = 32;

    if (publicKey[0] != (2 + 2 * keyLength) - 1)
        throw new ArgumentException("Invalid key length", nameof(publicKey));
    if (publicKey[1] != 0x04)
        throw new ArgumentException("Invalid key format", nameof(publicKey));

    var parameters = new ECParameters()
    {
        Curve = ECCurve.NamedCurves.brainpoolP256r1,
        Q = new ECPoint()
        {
            X = publicKey.Skip(2).Take(keyLength).ToArray(),
            Y = publicKey.Skip(2 + keyLength).Take(keyLength).ToArray()
        }
    };

    using (var tmp = ECDiffieHellman.Create(parameters))
    {
        return tmp.PublicKey;
    }
}
  1. 生成我尝试过的密钥
var ecdh = new ECDiffieHellmanCng(ECCurve.NamedCurves.brainpoolP256r1);
ecdh.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Tls;
ecdh.Seed = new byte[32];
ecdh.Label = Encoding.ASCII.GetBytes("ECDiffieHellman");

new RNGCryptoServiceProvider().GetBytes(ecdh.Seed);

// ...

var sharedSecret = ecdh.DeriveKeyMaterial(peersPublicKey);

我的问题是,与mbed TLS生成的共享密钥相比,生成的共享密钥的长度不同,并且不匹配。

有人已经解决了这个问题吗?

谢谢!

编辑1:

我忘了提到,我在ARM上使用裸ECDH。因此,我认为没有任何密钥派生函数正在执行。哈希(SHA256)结果以匹配C#端是否足够(当在那里将SHA256配置为KDF时)?

c# c elliptic-curve diffie-hellman mbedtls
1个回答
0
投票

我解决了问题。简而言之:只需哈希ECDH结果即可。

C / C ++面:

  1. EC Diffie Hellman
mbedtls_ecdh_init(...);
mbedtls_ecdh_setup(...);
mbedtls_ecdh_make_public(...); //make own public key and send it to peer
mbedtls_ecdh_read_public(...); //reed peers public key
mbedtls_ecdh_calc_secret(...); //note: i pass in my own RND func because of no OS
mbedtls_ecdh_free(...);
  1. SHA256
mbedtls_sha256_init(...);
mbedtls_sha256_starts_ret(...);
mbedtls_sha256_update_ret(...);
mbedtls_sha256_finish_ret(...);
mbedtls_sha256_free(...);

C#面:

private void EllipticCurveDiffieHellman()
{
    var ecdh = new ECDiffieHellmanCng(ECCurve.NamedCurves.brainpoolP256r1);

    ecdh.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
    ecdh.HashAlgorithm = CngAlgorithm.Sha256;

    //get relevant point from own public key
    var ownPublicKey = ecdh.PublicKey.ExportExplicitParameters().Q;

    var peersPublicKey = SendPublicKey(ownPublicKey); //key exchange
    var sharedSecret = ecdh.DeriveKeyMaterial(peersPublicKey);

    Console.WriteLine("Key: " + HexValue.Parse(sharedSecret.ToArray()));
}

DiffieHellmanPublicKey ToPublicKey(byte[] publicKey)
{
    var keyLength = 32;

    if (publicKey[0] != (2 + 2 * keyLength) - 1)
        throw new ArgumentException("Invalid key length", nameof(publicKey));
    if (publicKey[1] != 0x04)
        throw new ArgumentException("Invalid key format", nameof(publicKey));

    var parameters = new ECParameters()
    {
        Curve = ECCurve.NamedCurves.brainpoolP256r1,
        Q = new ECPoint()
        {
            X = publicKey.Skip(2).Take(keyLength).ToArray(),
            Y = publicKey.Skip(2 + keyLength).Take(keyLength).ToArray()
        }
    };

    using (var tmp = ECDiffieHellman.Create(parameters))
    {
        return tmp.PublicKey;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.