【问题标题】:Diffie-Hellman Key Exchange with Javascript sometimes wrong使用 Javascript 进行 Diffie-Hellman 密钥交换有时会出错
【发布时间】:2014-07-10 13:33:16
【问题描述】:

看完这个视频 http://youtu.be/3QnD2c4Xovk

我一直在尝试一步一步地遵循它,但未能产生相同的结果。

值得注意的是,当我尝试执行 Math.pow(3, 54)%17 时,我得到 7。而扬声器得到 15。

我编写了一个方法,该方法应该使用我在 http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange 上找到的内容来模拟 Diffie Hellman 的密钥交换

这是我的代码:

function diffieHellman(generator, prime, alice_secret, bob_secret){
  var alice_public = Math.pow(generator, alice_secret)%prime
    , bob_public = Math.pow(generator, bob_secret)%prime
    , alice_private = Math.pow(bob_public, alice_secret)%prime
    , bob_private = Math.pow(alice_public, bob_secret)%prime;
  console.log("alice"
  , "\n\t", "secret -- ", alice_secret
  , "\n\t", "public -- ", alice_public
  , "\n\t", "private -- ", alice_private
  )
  console.log("bob"
  , "\n\t", "secret -- ", bob_secret
  , "\n\t", "public -- ", bob_public
  , "\n\t", "private -- ", bob_private
  )
  return {
    alice:{
      secret: alice_secret
    , public: alice_public
    , private: alice_private
    },
    bob:{
      secret: bob_secret
    , public: bob_public
    , private: bob_private
    }
  }
};

这些示例有效:

diffieHellman(3, 17, 4, 12) // 1, 1
diffieHellman(3, 23, 6, 19) // 12, 12
diffieHellman(3, 13, 8, 4) // 9, 9

但是,有些数字不起作用

diffieHellman(3, 17, 40, 120) // 13, 0
diffieHellman(3, 23, 16, 129) // 21, 2
diffieHellman(3, 13, 44, 11) // 9, 1

我做错了什么?

编辑——我不想在项目的 Javascript 中实现 Diffie-Hellman 的密钥交换。这只是我最熟悉的语言,但我担心这可能是 javascript 的限制。

【问题讨论】:

  • 您正在尝试使用一种将所有数字存储为浮点数的语言进行大规模整数数学运算。您将需要真正的整数类型。
  • (3^54) mod 17 = 15 所以这里 Javascript 可能不是正确的选择(我在 Chrome 中也得到 7)

标签: javascript public-key-encryption diffie-hellman


【解决方案1】:

问题是 Javascript 数字的有限精度导致代码中的舍入错误,您首先取幂然后计算模数。对于您的示例数字,您可以通过定期计算取幂内的模数来解决此问题,例如在取模之前从不计算超过一个平方。但是对于实际的密码学,您的计算将涉及太大而无法作为 Javascript 数字处理的数字(并且大多数编程语言都存在同样的问题)。通常的方法是使用大整数(甚至是任意精度)库。如果您最终实现了自己的加密,请注意旁道,例如通过调用非恒定时间的库函数或允许使用数据相关数组索引进行基于缓存的攻击。

【讨论】:

    【解决方案2】:

    3^54 是 58149737003040059690390169。它会导致溢出,因此你应该实现modular exponentation,因为我不太了解 javascript,我编写了一个 c 代码,应该很容易在 javascript 中实现:

    int power(int a, int b, int prime){
          int result;
          if(b == 0){
               result = 1;
          }else if(b == 1){
               result = a % prime;
          }else if(b % 2 == 0){
               result = power((a*a) % prime, b/2, prime);
               result = result % prime;
          }else{
               result = power((a*a) % prime, b/2, prime);
               result = (result * a) % prime;
          }
      return result;
      }
    

    现在你可以调用这个函数了:

    int value = power(3, 54, 17);
    

    它应该可以工作。

    编辑:添加 javascript 版本

    function power(a, b, prime) {
        if (b <= 0) {
            return 1;
        } else if (b === 1) {
            return a % prime;
        } else if (b % 2 === 0) {
            return power((a * a) % prime, b / 2 | 0, prime) % prime;
        } else {
            return (power((a * a) % prime, b / 2 | 0, prime) * a) % prime;
        }
    }
    

    【讨论】:

    • 我尝试将此函数用于我自己的模幂运算,但没有得到预期的输出。我找到了另一个对我有用的实现here。
    • @darksinge 你现在可以检查一下我已经修改了这个功能,它现在应该可以工作了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2023-03-03
    • 1970-01-01
    • 2014-05-13
    • 1970-01-01
    • 2018-06-10
    相关资源
    最近更新 更多