证书钉扎xamarin形式

问题描述 投票:0回答:2

对如何进行证书固定感到困惑。我们如何通过xmarin表单在n android或ios设备中安装证书。如果应用程序在安装期间完成吗?有一些关于如何使用固定来验证https请求但没有安装公共证书的导师?

xamarin xamarin.forms ssl-certificate pinning
2个回答
1
投票

另一种方法是在叶子的证书公钥上执行固定,在this simple demo class中,我们可以通过自定义ServicePointManager来查看如何使用HttpClient:

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
投票

虽然您可以使用证书本身来执行验证,从而固定证书,但还有其他选项。

根据OWASP documentation here,您可以实现以下3种方法中的任何一种:

证书

证书最容易固定。您可以从网站上获取带外证书,让IT人员通过电子邮件向您发送公司证书,使用openssl s_client检索证书等。证书过期后,您将更新您的申请。假设您的应用程序没有错误或安全缺陷,应用程序将每年或每两年更新一次。在运行时,您将在回调中检索网站或服务器的证书。在回调中,您将检索到的证书与程序中嵌入的证书进行比较。如果比较失败,则方法或功能失败。

钉住证书有一个缺点。如果站点定期轮换其证书,则需要定期更新您的应用程序。例如,Google会轮换其证书,因此您需要每月更新一次应用程序(如果它依赖于Google服务)。即使Google轮换其证书,底层公钥(在证书中)仍然是静态的。

公钥

由于从证书中提取公钥所需的额外步骤,公钥锁定更灵活,但有点棘手。与证书一样,程序使用其公钥的嵌入副本检查提取的公钥。两个公钥固定有两个缺点。首先,由于您通常必须从证书中提取密钥,因此更难使用密钥(而不是证书)。在Java和.Net中,提取是一个小小的不便,但它在Cocoa / CocoaTouch和OpenSSL中很不舒服。其次,密钥是静态的,可能违反密钥轮换策略。

哈希

虽然上面的三个选择使用DER编码,但也可以使用信息的散列(或其他变换)。事实上,原始的示例程序是使用消化的证书和公钥编写的。更改样本以允许程序员使用dumpasn1和其他ASN.1解码器等工具检查对象。

哈希还提供了三个额外的好处。首先,哈希允许您匿名化证书或公钥。如果您的应用程序担心在反编译和重新设计期间泄漏信息,这可能很重要。

其次,消化的证书指纹通常可用作许多库的本机API,因此使用起来非常方便。

最后,组织可能希望在主要身份被泄露的情况下提供保留(或备份)身份。散列可确保您的对手在使用之前不会看到保留的证书或公钥。实际上,谷歌的IETF草案websec-key-pinning使用了这种技术。

我强烈建议使用Hashing方法,这意味着当您验证进入的证书时,您只需要检查来自服务器的证书的哈希是否是您期望的那个。类似于以下内容:

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"
};
© www.soinside.com 2019 - 2024. All rights reserved.