c# - ECDiffieHellman-mbedTLS与C#

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

我需要在手臂皮层M3和电脑之间使用椭圆曲线Diffie-Hellman。
在手臂上,我使用mbed TLS。在个人电脑方面,我希望我们是C#和ECDiffieHellman(Cng)类。
我可以在ARM和ARM上做ECDH,但是当我试图用PC替换一侧时,我确实遇到了麻烦。
问题是密钥交换。
我发现,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;
    }
}

生成我尝试的密钥
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:
我忘了说,我手臂上用的是赤裸的ECDH。所以我认为没有任何键派生函数在执行。散列(SHA256)结果是否足以匹配C端(在那里将SHA256配置为KDF时)?

最佳答案

我解决了这个问题。简而言之:只是散列ECDH结果。
C/C++侧:
欧共体迪菲赫尔曼

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(...);

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;
    }
}

相关文章:

ios - ECDH从OpenSSL和BouncyCastle派生的共享密钥并不总是相同,尽管两者的常量和域参数相同

c# - 声明语句以比较两个文件是否相等

c# - '做'而'与'同时'

php - 在Windows上的php中执行C程序

node.js - BitCore中用于分层密钥的node.js钱包导入格式(WIF)

c - 在C中找到分段错误的解决方案

c# - 在IDialog中使用ILifetimeScope

c# - 用Linq查询连接两个字段

c# - 将泛型添加到表单

c - 有没有办法从库中识别有关内存分配的详细信息