【问题标题】:Exception / hang on Mono.Security Diffie-Helman key generation for SSH Transport为 SSH 传输生成 Mono.Security Diffie-Hellman 密钥时出现异常/挂起
【发布时间】:2013-06-27 06:03:04
【问题描述】:

我正在尝试通过 SSH 在 Ngit 上进行推送。我正在使用此处列出的方法指定我自己的密钥:NGit making a connection with a private key file

它适用于克隆,并且在第一次推送时。在那之后,它有 30% 的时间失败了,在 Mono.Security 中总是在这个方法中:

Mono.Security.dll!Mono.Math.BigInteger.Kernel.MinusEq(Mono.Math.BigInteger big, Mono.Math.BigInteger small)

要么失败并显示消息:“在加密函数期间发生错误”,要么在此函数中无限期挂起。同样,它是否成功似乎完全随机。它被 NGit 中的函数调用:

DiffieHellmanManaged dh = new DiffieHellmanManaged (pspec.P.GetBytes (), pspec.G.GetBytes (), 0);

在 GenerateKeyPair (KeyPairGenerator.cs)中

有什么想法吗?如果没有,有什么方法可以通过其他方法生成 Diffie-Helman 密钥?

非常感谢,

干杯,

更新:我发现了一个我不完全理解的奇怪解决方案:

之前,我创建了一个新线程,因为我从 UI 调用它并且不希望它挂起。这是一个 STA 线程,因为我们正在构建一个 VSTO 应用程序,它不支持来自 UI 组件的 MTA / BackgroundWorker() 等(几乎限制了您使用旧的 Thread(),因为您可以根据需要指定它是 STA )。我发现当用户在推送过程中点击周围时问题更频繁地发生(因此进行了一些 git checkouts),所以我禁用了线程并直接从 UI 运行它。从那时起,它像地狱一样冻结了 UI,但不会在 BigInt 的计算上挂起 pr crash。对于这种情况,我完全感到困惑,除非:Office(我们正在为其构建插件)以某种方式无法为 BigInt 计算提供具有足够内存的线程(或对该内存管理不善,这并不完全令人惊讶) ,或者,由于某种原因,BigInt 计算根本无法在线程上下文中调用(可能是 Thread->Ngit->Sharpen->Mono.Security->Mono.Math(32 digit number)断线??)

知道这可能是什么原因吗?

【问题讨论】:

    标签: c# git ngit


    【解决方案1】:

    我在使用 NGit + SSH 私钥从 Git 存储库中获取/拉取时遇到了完全相同的问题,这可以从多个线程中请求。

    Mono.Security Mono.Math.BigInteger 在多线程上下文中运行时,我发现它是一个问题(可以找到错误报告和复制它的代码here)。尽管无论出于何种原因,我只能在 Windows 环境中复制该问题。在 OSX 的 Mono 上,它似乎工作得很好。

    为了解决问题,我最终将 NSch 更改为使用 DiffieHellmanManaged 的​​修改实现,它使用与 System.Numerics.BigInteger 相同的逻辑计算 BigIntegers 本身的 ModPow。

    public static BigInteger ModPower(this BigInteger value, BigInteger exp, BigInteger n)
        {
            if (exp < 0)
                throw new ArgumentOutOfRangeException("exponent", "power must be >= 0");
            if (n == 0)
                throw new DivideByZeroException();
    
            BigInteger result = new BigInteger(1) % n;
            while (exp != 0)
            {
                if (exp % 2 != 0)
                {
                    result = result * value;
                    result = result % n;
                }
                if (exp == 1)
                    break;
                value = value * value;
                value = value % n;
                exp >>= 1;
            }
            return result;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 2023-03-19
      相关资源
      最近更新 更多