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