TlsException: аутентификация или дешифрование не удалось при использовании HttpWebRequest [duplicate]

Мне нужно было рассчитать множество расстояний между точками моего проекта, поэтому я пошел дальше и попытался оптимизировать код, который я нашел здесь. В среднем в разных браузерах моя новая реализация выполняется в 2 раза быстрее, чем самый предыдущий ответ.

function distance(lat1, lon1, lat2, lon2) {
  var p = 0.017453292519943295;    // Math.PI / 180
  var c = Math.cos;
  var a = 0.5 - c((lat2 - lat1) * p)/2 + 
          c(lat1 * p) * c(lat2 * p) * 
          (1 - c((lon2 - lon1) * p))/2;

  return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}

Вы можете играть с моим jsPerf и видеть результаты здесь .

Недавно мне нужно было сделать то же самое в python, так что вот реализация python:

from math import cos, asin, sqrt
def distance(lat1, lon1, lat2, lon2):
    p = 0.017453292519943295
    a = 0.5 - cos((lat2 - lat1) * p)/2 + cos(lat1 * p) * cos(lat2 * p) * (1 - cos((lon2 - lon1) * p)) / 2
    return 12742 * asin(sqrt(a))

И ради полноты: Haversine на wiki.

66
задан jww 26 December 2016 в 12:45
поделиться

10 ответов

Mono не доверяет никакому сертификату по умолчанию, чтобы импортировать доверенные корневые полномочия Mozilla, которые вы можете запустить mozroots --import --quiet в папке с моноустановкой, где находится mozroots.exe

2
ответ дан LiriB 19 August 2018 в 10:54
поделиться

Еще одно решение для Unity - инициализировать ServicePointManager один раз, чтобы всегда принимать сертификаты. Это работает, но, очевидно, небезопасно.

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
           delegate (object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                                   System.Security.Cryptography.X509Certificates.X509Chain chain,
                                   System.Net.Security.SslPolicyErrors sslPolicyErrors)
           {
               return true; // **** Always accept
       };
2
ответ дан Erik Kalkoken 19 August 2018 в 10:54
поделиться

В первом ответе уже сказано: Mono ни на что другое, кроме Windows, не приходит ни с чем, поэтому изначально он не доверяет никакому сертификату. Итак, что делать?

Вот хорошая статья о различных способах решения проблемы с точки зрения разработчика: http://www.mono-project.com/archived/usingtrustedrootsrespectfully/

Краткое описание: вы можете:

  • игнорировать проблему безопасности
  • игнорировать проблему
  • , чтобы user know and abort
  • позволяет пользователю узнать и дать ему возможность продолжать свой собственный риск

Вышеупомянутая ссылка содержит примеры кода для каждого случая.

2
ответ дан Gerhard 19 August 2018 в 10:54
поделиться
  • 1
    вызов mozroots --import --sync должен исправить его для вас, добавив сертификаты по умолчанию из mozilla в хранилище моно хранилищ. – ScottB 17 October 2015 в 10:57

У меня была та же проблема. Когда HTTP-ответ вызывает это исключение, я делаю следующее:

System.Diagnostics.Process.Start("mozroots","--import --quiet");

импортирует недостающие сертификаты, а исключение никогда не происходит снова.

3
ответ дан harry4516 19 August 2018 в 10:54
поделиться

Я тоже сталкиваюсь с ошибкой.

Я попробовал ServicePointManager.ServerCertificateValidationCallback и ServicePointManager.CertificatePolicy, но все еще не работал.

Я гнев. создайте обертку cURL. Это отлично работает для моего игрушечного проекта.

/// <summary>
/// For MONO ssl decryption failed
/// </summary>
public static string PostString(string url, string data)
{
    Process p = null;
    try
    {
        var psi = new ProcessStartInfo
        {
            FileName = "curl",
            Arguments = string.Format("-k {0} --data \"{1}\"", url, data),
            RedirectStandardOutput = true,
            UseShellExecute = false,
            CreateNoWindow = false,
        };

        p = Process.Start(psi);

        return p.StandardOutput.ReadToEnd();
    }
    finally
    {
        if (p != null && p.HasExited == false)
            p.Kill();
    }
}
3
ответ дан IlPADlI 19 August 2018 в 10:54
поделиться

Вы можете установить реализацию Mono TLS в iOS Build, и все будет работать нормально, как описано здесь: http://massivepixel.co/blog/post/xamarin-studio-6-certificate-unknown ( хотя Mono TLS не поддерживает более новые версии TLS, но я еще не столкнулся с проблемой, что это проблема).

0
ответ дан Ivan Ičin 19 August 2018 в 10:54
поделиться

Запишите эту строку перед запросом HTTP запроса. это должно быть работой.

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback((sender, certificate, chain, policyErrors) => { return true; });


private static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        //Return true if the server certificate is ok
        if (sslPolicyErrors == SslPolicyErrors.None)
            return true;

        bool acceptCertificate = true;
        string msg = "The server could not be validated for the following reason(s):\r\n";

        //The server did not present a certificate
        if ((sslPolicyErrors &
             SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable)
        {
            msg = msg + "\r\n    -The server did not present a certificate.\r\n";
            acceptCertificate = false;
        }
        else
        {
            //The certificate does not match the server name
            if ((sslPolicyErrors &
                 SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
            {
                msg = msg + "\r\n    -The certificate name does not match the authenticated name.\r\n";
                acceptCertificate = false;
            }

            //There is some other problem with the certificate
            if ((sslPolicyErrors &
                 SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)
            {
                foreach (X509ChainStatus item in chain.ChainStatus)
                {
                    if (item.Status != X509ChainStatusFlags.RevocationStatusUnknown &&
                        item.Status != X509ChainStatusFlags.OfflineRevocation)
                        break;

                    if (item.Status != X509ChainStatusFlags.NoError)
                    {
                        msg = msg + "\r\n    -" + item.StatusInformation;
                        acceptCertificate = false;
                    }
                }
            }
        }

        //If Validation failed, present message box
        if (acceptCertificate == false)
        {
            msg = msg + "\r\nDo you wish to override the security check?";
//          if (MessageBox.Show(msg, "Security Alert: Server could not be validated",
//                       MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                acceptCertificate = true;
        }

        return acceptCertificate;
    }
7
ответ дан Pawan Chaurasiya 19 August 2018 в 10:54
поделиться
  • 1
    Пожалуйста, подумайте над тем, чтобы включить некоторую информацию о вашем ответе, а не просто отправлять код. Мы стараемся предоставлять не только «исправления», но и помогать людям учиться. Вы должны объяснить, что было не так в исходном коде, что вы сделали по-другому и почему ваши изменения (ы) работали. – Andrew Barber 3 December 2014 в 21:53
  • 2
    Это противоречит разумной безопасности в Интернете: вы просто принимаете какой-либо сертификат без предварительной проверки. См. Ответ @Ludovic для функции, которая проверяет перед принятием. – ssamuel 3 June 2016 в 19:58
  • 3
    Это отклоняет подкласс ошибок SSL, но молча разрешает другим (например, самоподписанные сертификаты). Таким образом (как и другие ответы здесь), это эффективно отключает все преимущества безопасности SSL. Если это то, что вы хотите, просто return true;. – Søren Løvborg 5 July 2018 в 13:22

В .NET Framework в Windows используется хранилище сертификатов Windows (mmc, Add / Remove Snap-Ins, Certificates), чтобы определить, следует ли принимать сертификат SSL с удаленного сайта. Windows поставляется с кучей корневых и промежуточных центров сертификации (CA), и они периодически обновляются с помощью Центра обновления Windows. В результате ваш код .NET, как правило, будет доверять сертификату, если он был выпущен CA или потомок CA в хранилище сертификатов (включены наиболее авторитетные коммерческие ЦС).

В Mono нет хранилища сертификатов Windows. У Моно есть собственный магазин. По умолчанию он пуст (нет доверенных ЦС по умолчанию). Вам нужно управлять своими записями самостоятельно.

Взгляните сюда:

Точка mozroots.exe заставит вашу моноустановку доверять всем, что доверяет Firefox после установки по умолчанию.

27
ответ дан scottt732 19 August 2018 в 10:54
поделиться
  • 1
    Краткая заметка здесь о корневом сертификате Entrust's G2, который в настоящее время НЕ включен в хранилище CA Mozilla. Они планируют добавить его для выпуска Firefox 38, но это не гарантировано. В настоящее время, если вы используете хранилище CA Mozilla, ваш код не сможет проверить сертификаты, подписанные с корневым сертификатом G2. (Thumbprints находятся в entrust.net/developer , ошибка Mozilla из 2013 находится в bugzilla.mozilla.org/show_bug.cgi?id=849950 ) – Benjamin Nolan 5 April 2015 в 16:03

У меня была та же проблема с Unity (которая также использует mono) и , этот пост помог мне решить ее.

Просто добавьте следующую строку перед тем, как сделать свой запрос:

ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;

И этот метод:

public bool MyRemoteCertificateValidationCallback(System.Object sender,
    X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    bool isOk = true;
    // If there are errors in the certificate chain,
    // look at each error to determine the cause.
    if (sslPolicyErrors != SslPolicyErrors.None) {
        for (int i=0; i<chain.ChainStatus.Length; i++) {
            if (chain.ChainStatus[i].Status == X509ChainStatusFlags.RevocationStatusUnknown) {
                continue;
            }
            chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
            chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
            chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan (0, 1, 0);
            chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
            bool chainIsValid = chain.Build ((X509Certificate2)certificate);
            if (!chainIsValid) {
                isOk = false;
                break;
            }
        }
    }
    return isOk;
}
43
ответ дан sharptooth 19 August 2018 в 10:54
поделиться
  • 1
    Это должно работать на самом деле, но в моем swagger автогенераторе, похоже, нет. См. github.com/swagger-api/swagger-editor/issues/1034 – loretoparisi 2 August 2016 в 15:20
  • 2
    Работали как обаяние. (Y), – Emy Stats 20 October 2016 в 14:23
  • 3
    Существует потенциальная проблема, что chain.Build(cert) всегда возвращает true в mono even request к bad ssl . – sakiM 5 February 2018 в 08:52
  • 4
    Извините, но ваше решение заключалось в сворачивании собственной проверки сертификата SSL с помощью случайного кода , найденного в Интернете? Если вам не нужна безопасность, предлагаемая SSL, просто используйте свою функцию return true;. Это просто «безопасность благодаря энергичной руке» и действительно полностью нарушена и с радостью примет сломанные или поддельные сертификаты. – Søren Løvborg 5 July 2018 в 13:16
0
ответ дан Owen Pauling 30 October 2018 в 23:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: