【问题标题】:Diffie-Hellman with BIGNUM (OpenSSL) vs. BigInteger (C#)使用 BIGNUM (OpenSSL) 与 BigInteger (C#) 的 Diffie-Hellman
【发布时间】:2015-01-17 22:57:02
【问题描述】:

我正在使用 OpenSSL 库进行 BIGNUM 操作的嵌入式设备和使用 System.Numerics.BigInteger 方法计算秘密共享密钥生成的 C# 软件之间实现 Diffie-Hellman 密钥交换算法。

但是在 Alice 和 Bob 交换密钥之后,他们计算出不同的共享秘密。

每边都打印出密钥(PubA, PrivA, PubB, PrivB, DHPrime, DHGenerator),我可以看到它们是相同的。

我怀疑存在关于小/大字节序的问题,或者 openssl 不关心指数的负数,我不知道如何调试这些操作。我现在没有代码,但所有操作都保持简单,就像这样。

C#端

BigInteger bintA = new BigInteger(baByteArrayReceived);
BigInteger bintb = new BigInteger(baRandomBobSecret);
BigInteger bintDHPrime = new BigInteger(baDHPrime2048);

BigInteger bintSharedSecret = bintA.ModPow(bintb,bintDHPrime);

C端

BIGNUM *bnB = BN_new();
BIGNUM *bna = BN_new();
BIGNUM *bnDHPrime = BN_new();
BIGNUM *bnResult = BN_new();
BN_CTX *bnctx = BN_CTX_new();

BN_bin2bn(baBReceived, 256,bnB);
BN_bin2bn(baRandomAliceSecret, 256,bna);
BN_bin2bn(baDHPrime2048, 256,bnDHPrime);

BN_mod_exp(bnResult,bnB,bna,bnDHPrime,bnctx);

OpenSSL 的 C 方法的一些附加信息: >

BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret);

BN_bin2bn 集|*ret|到 |len| 的值来自|in| 的字节,解释为大端数,并返回|ret|。如果 |ret|为 NULL 则为新的 |BIGNUM|被分配并返回。它在分配失败时返回 NULL。

 int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 
     const BIGNUM *m, BN_CTX *ctx);

BN_mod_exp 集|r|等于 |a|^{|p|} mod |m|。它使用提供的值的最佳算法来执行此操作,并且如果 |BN_FLG_CONSTTIME| 可以在恒定时间内运行设置为 |p|。成功则返回 1,否则返回 0。

它们会产生不同的结果。

我该怎么办?你接下来要检查什么?

提前致谢。

【问题讨论】:

  • 如果这只是 C# 开发(使用 OpenSSL 验证结果),那么您应该转到 Crypto++。它更清洁,更易于使用。 C++ 中的运算符重载使得做大数学变得非常容易(根据经验)。
  • 通常您使用公钥和私钥部分。因此,对于未经身份验证的 DH (ephemeral-ephemeral),有六个对象在起作用:pubAprivAsharedApubBprivBsharedB。看起来你缺少一些片段。经过身份验证的 DH(临时静态)为 A 和 B 添加了长期密钥,因此还有四个似乎丢失了。
  • “我正在嵌入式设备之间实现 Diffie-Hellman 密钥交换算法...” - 对于低功耗、资源受限的设备,您通常避免使用 DH,因为它太昂贵了。在这种情况下,通常使用预共享密钥协议,例如预共享密钥 (PSK)。 PSK 是Password Authenticated Key Exchange (PAKE)。安全远程密码 (SRP) 是另一个 PAKE,但它的根本问题是 Diffie-Hellman(您通常会避免)。
  • @jww,我们可以访问双方的代码级别,但是在这些设备之间应用 diffie-hellman 是必须的,我们没有决定。这使得 openssl(也用于嵌入式端的其他部分)对我们来说更加重要。问题是,当输入相同时,我们如何确保双方计算相同?

标签: c# c openssl biginteger diffie-hellman


【解决方案1】:

通过使用 BouncyCastle Crypto Library 的 BigInteger 方法解决。无法告诉 System.Numerics.BigInteger 我们正在使用大端无符号字符进行初始化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 2021-04-27
    • 1970-01-01
    相关资源
    最近更新 更多