SSH传输的Mono.Security Diffie-Helman密钥生成异常/挂起

时间:2013-06-27 06:03:05

标签: c# git ngit

我正试图在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检查),所以我禁用了线程并直接从UI运行它。从那时起,它就像地狱一样冻结了用户界面,但是并没有因为BigInt的计算而崩溃。我对这种情况完全感到困惑,除非:Office(我们正在构建插件)以某种方式不会为BigInt计算提供足够内存的线程(或者错误管理这个内存,这不会完全令人惊讶) ,或者,由于某种原因,BigInt计算根本无法在线程上下文中调用(可能是Thread-&gt; Ngit-&gt; Sharpen-&gt; Mono.Security-&gt; Mono.Math( 32位数< / em>)破坏了线程??)

任何想法可能是什么原因?

1 个答案:

答案 0 :(得分:0)

当使用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;
    }