c# - ECDiffieHellman - mbedTLS 与 C#

标签 c# c elliptic-curve diffie-hellman mbedtls

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

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

  1. 问题出在 key 交换上。 我发现, key 由 mbed TLS 导出为 <LEN><0x04><X><Y> .

因此,在 C# 中,我使用

导入公钥

私有(private)静态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. 生成我试过的 key
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);

我的问题是生成的共享 key 与 mbed TLS 生成的共享 key 的长度不同并且不匹配。

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

谢谢!

编辑 1:

我忘了说,我在 ARM 上使用裸 ECDH。所以我认为没有任何 key 派生函数在执行。对结果进行散列 (SHA256) 以匹配 C# 端是否足够(在此处将 SHA256 配置为 KDF 时)?

最佳答案

我解决了这个问题。简而言之:只需散列 ECDH 结果。

C/C++ 端:

  1. 欧共体迪菲赫尔曼
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;
    }
}

关于c# - ECDiffieHellman - mbedTLS 与 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58167034/

相关文章:

c# - 带有复选框 where 条件组合的 linq to sql 查询

c# - 在运行时将 CSS 添加到 ASP.net 母版页。

C# 获取 SelectedDate.Day 字符串值并将其绑定(bind)到 gridview

c - 需要在函数前加上 (void)

c - mpi_gather,c 中的二维动态数组,在信号 6 上退出(中止)

EC 公钥/私钥的文件格式?

python - 椭圆曲线暴力破解

C#按优先级获取第一个非空属性

node.js - 有没有办法在node.js加密模块上获取用于ECDH的基点(P)?

c++ - 错误 : variable or field ‘myfunction’ declared void