Сертификат закрепления формы ксамарин - PullRequest
0 голосов
/ 24 мая 2018

Запутался, как сделать закрепление сертификата.Как нам установить сертификат в Android и IOS устройства с помощью форм xmarin.Это делается во время установки приложения?Есть несколько уроков о том, как использовать проверку запросов https с помощью закрепления, но ничего об установке общедоступного сертификата?

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Другой способ - это закрепить открытый ключ сертификата листа, и в этом простом демонстрационном классе мы можем увидеть, как это сделать при использовании HttpClient, настроив ServicePointManager:

using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace ApproovSDK
{
    /**
     * Service point configuration.
     * 
     * Adds simple pinning scheme to service point manager.
     * 
     * FOR DEMONSTRATION PURPOSES ONLY
     */
    public static class ServicePointConfiguration
    {
        private static string PinnedPublicKey = null;

        public static void SetUp(string key = null)
        {
            PinnedPublicKey = key;

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertficate;
        }

        private static bool ValidateServerCertficate(
            object sender,
            X509Certificate certificate,
            X509Chain chain,
            SslPolicyErrors sslPolicyErrors
        )
        {
            if (PinnedPublicKey == null || PinnedPublicKey.Length <= 0) return true;

            //Console.WriteLine("Expected: " + PinnedPublicKey);
            //Console.WriteLine("Found   : " + certificate?.GetPublicKeyString());

            return String.Equals(PinnedPublicKey, certificate?.GetPublicKeyString(),
                                 StringComparison.OrdinalIgnoreCase);
        }
    }
}

Приведенный выше пример был написан для демонстрационной цели, и лучшая реализация должна ассоциировать несколько ключей для каждого вызываемого домена.

0 голосов
/ 12 сентября 2018

Хотя вы можете использовать сам сертификат для выполнения проверки и, таким образом, закрепления сертификата, существуют альтернативные варианты.

Согласно документации OWASP здесь вы можете реализовать любой изследующие 3 подхода:

Сертификат

Сертификат проще всего прикрепить.Вы можете получить сертификат для веб-сайта, получить от ИТ-специалистов сертификат вашей компании, использовать openssl s_client для получения сертификата и т. Д. Когда срок действия сертификата истечет, вы обновите свое приложение.Предполагая, что в вашем приложении нет ошибок или дефектов безопасности, оно будет обновляться каждый год или два.Во время выполнения вы извлекаете сертификат веб-сайта или сервера в обратном вызове.В рамках обратного вызова вы сравниваете полученный сертификат с сертификатом, встроенным в программу.Если сравнение не удастся, произойдет сбой метода или функции.

У закрепления сертификата есть и обратная сторона.Если сайт регулярно обновляет свой сертификат, то ваше приложение должно регулярно обновляться.Например, Google чередует свои сертификаты, поэтому вам нужно будет обновлять приложение примерно раз в месяц (если это зависит от служб Google).Несмотря на то, что Google вращает свои сертификаты, базовые открытые ключи (внутри сертификата) остаются статичными.

Открытый ключ

Пиннинг открытого ключа - это большегибкий, но немного сложнее из-за дополнительных шагов, необходимых для извлечения открытого ключа из сертификата.Как и в случае с сертификатом, программа проверяет извлеченный открытый ключ со встроенной копией открытого ключа.Есть два недостатка, два закрепления открытых ключей.Во-первых, с ключами труднее работать (по сравнению с сертификатами), поскольку обычно вы должны извлечь ключ из сертификата.Извлечение - небольшое неудобство в Java и .Net, но это неудобно в Cocoa / CocoaTouch и OpenSSL.Во-вторых, ключ является статическим и может нарушать политику ротации ключей.

Хеширование

Хотя три вышеупомянутых варианта используют кодировку DER, его также допустимоиспользовать хеш информации (или другие преобразования).Фактически, оригинальные примеры программ были написаны с использованием переваренных сертификатов и открытых ключей.Образцы были изменены, чтобы позволить программисту проверять объекты с помощью таких инструментов, как dumpasn1 и другие декодеры ASN.1.

Хеширование также дает три дополнительных преимущества.Во-первых, хеширование позволяет анонимизировать сертификат или открытый ключ.Это может быть важно, если ваше приложение обеспокоено утечкой информации во время декомпиляции и реинжиниринга.

Во-вторых, отпечатанный отпечаток сертификата часто доступен как собственный API для многих библиотек, поэтому его удобно использовать.

Наконец, организация может захотеть предоставить резервный (или резервный) идентификатор на случай, если основной идентификатор будет скомпрометирован.Хеширование гарантирует, что ваши злоумышленники не увидят зарезервированный сертификат или открытый ключ до его использования.Фактически, в проекте IETF Google для закрепления ключей websec используется эта техника.

Я бы настоятельно рекомендовал использовать подход хеширования, означающий, что при проверке входящего сертификата вам просто нужно проверить, что хешсертификат, исходящий от сервера, - это тот, который вы ожидаете.Что-то вроде следующего:

private bool ValidateServerCertificate(object sender,
                                       X509Certificate certificate,
                                       X509Chain chain,
                                       SslPolicyErrors sslPolicyErrors)
{
    // Make sure we have a certificate to check.
    if (certificate == null)
    {
        return false;
    }

    if (sslPolicyErrors != SslPolicyErrors.None)
    {
        return false;
    }

    return this.KnownKeys.Contains(certificate.GetCertHashString(), 
                                   StringComparer.Ordinal);
}

Где KnownKeys - это простой, определенный во время компиляции массив известных хэшей сертификатов:

private readonly string[] KnownKeys = new[]
{
    "INSERT HASH",
    "AND A SECOND IF REQUIRED"
};
...