证书钉扎xamarin形式

时间:2018-05-24 14:11:31

标签: xamarin xamarin.forms ssl-certificate pinning

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

2 个答案:

答案 0 :(得分: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);
        }
    }
}

上面的示例是出于演示目的而编写的,更好的实现应针对每个被调用的域关联多个密钥。

答案 1 :(得分:0)

虽然您可以使用证书本身来执行验证,从而将证书固定在其他位置。

根据OWASP documentation here,您可以实施以下3种方法之一:

证书

  

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

     

固定证书有一个缺点。如果网站旋转   定期获得证书,那么您的申请将需要   定期更新。例如,Google旋转其证书,因此   您将需要每月大约更新一次应用程序(如果有的话)   取决于Google服务)。即使Google轮换了   证书,基础公钥(在证书内)   保持不变。

公钥

  

公钥固定更灵活,但由于   从证书中提取公钥所需的额外步骤。如   带有证书,程序将使用以下命令检查提取的公钥   嵌入的公钥副本。有两个缺点   公钥固定。首先,使用键更难(相对于   证书),因为您通常必须从   证书。在Java和.Net中,提取是一个不便之处,   但是在Cocoa / CocoaTouch和OpenSSL中感到不舒服。第二,   密钥是静态的,并且可能违反密钥轮换政策。

哈希

  

虽然上面的三个选择使用了DER编码,但也可以接受   使用信息的哈希(或其他转换)。实际上,   原始示例程序是使用摘要证书编写的,   公钥。更改了样本以允许程序员检查   使用dumpasn1和其他ASN.1解码器之类的工具来处理对象。

     

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

     

第二,通常可以使用摘要证书指纹作为   许多库的本地API,因此使用方便。

     

最后,组织可能希望提供备用(或备用)   主要身份被泄露时使用的身份。散列确保   您的对手看不到保留的证书或公钥   使用前。实际上,Google的IETF草案Websec-key-pinning   使用该技术。

我强烈建议您使用散列方法,这意味着当您验证传入的证书时,您只需要检查来自服务器的证书的散列是否符合您的期望即可。类似于以下内容:

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"
};