1

我正在尝试在 Ngit 上通过 SSH 进行推送。我正在使用此处列出的方法指定我自己的密钥: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 计算提供具有足够内存的线程(或对该内存管理不善,这不会32位数字)断线??)

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

4

1 回答 1

0

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

当Mono.Security Mono.Math.BigInteger在多线程上下文中运行时,我发现它是一个问题(可以在此处找到错误报告和复制它的代码)。尽管无论出于何种原因,我只能在 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;
    }
于 2014-04-10T20:35:18.463 回答