Исключение / зависание на Mono.Security Генерация ключа Диффи-Хелмана для SSH Transport

Я пытаюсь сделать толчки через SSH на NGit. Я указываю свои собственные ключи, используя метод, изложенный здесь: NGit устанавливает соединение с файлом закрытого ключа.

Хорошо работает с клоном и при первом нажатии. После этого происходит сбой 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)

Есть идеи? Если нет, есть ли способы генерировать ключи Диффи-Хелмана каким-то другим способом?

Спасибо,

Ура,

ОБНОВЛЕНИЕ: я обнаружил странное решение, которое я не совсем понимаю:

Ранее я создал новый поток, так как я вызывал его из пользовательского интерфейса и не хотел, чтобы он зависал. Это был поток STA, так как мы создаем приложение VSTO, и оно не поддерживает MTA / BackgroundWorker() и т. Д. Из компонентов пользовательского интерфейса (в значительной степени ограничивая вас старым потоком (), поскольку вы можете указать, что это STA по мере необходимости). Я обнаружил, что проблема возникает чаще, когда пользователь щелкает по кнопке во время выполнения push (таким образом, делая некоторые проверки git), поэтому я отключил многопоточность и запустил ее непосредственно из пользовательского интерфейса. С тех пор он замораживает пользовательский интерфейс, но не зависает при сбое при расчете BigInt. Я полностью озадачен тем, как это происходит, если: Office (для которого мы создаем аддоны) каким-то образом не предоставит потоку с достаточным объемом памяти для вычислений BigInt (или неправильно управляет этой памятью, что не было бы совершенно удивительно) или, по какой-то причине, вычисления BigInt просто не могут быть вызваны в многопоточном контексте (может быть, Thread-> Ngit-> Sharpen-> Mono.Security-> Mono.Math (32-значное число) прервал работу с потоками??)

Есть идеи, что может быть причиной этого?

1 ответ

У меня были точно такие же проблемы при использовании закрытого ключа NGit + SSH для извлечения / извлечения данных из репозитория Git, который можно было запрашивать из нескольких потоков.

Я обнаружил, что это проблема с Mono.Security Mono.Math.BigInteger, когда он запускается в многопоточном контексте (отчет об ошибке и код для его репликации можно найти здесь). Хотя по какой-то причине я мог воспроизвести проблему только в среде Windows. На Mono в OSX вроде все работало нормально.

Чтобы обойти эту проблему, я в итоге изменил NSch на использование модифицированной реализации DiffieHellmanManaged, которая вычисляла ModPow для самих BigIntegers, используя ту же логику, что и System.Numerics.BigInteger.

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;
    }
Другие вопросы по тегам