Aracılığıyla paylaş


TLS/SSL en iyi yöntemleri

TLS (Aktarım Katmanı Güvenliği), İnternet üzerinden iki bilgisayar arasındaki iletişimin güvenliğini sağlamak için tasarlanmış bir şifreleme protokolüdür. TLS protokolü sınıfı aracılığıyla .NET'te kullanıma sunulur SslStream .

Bu makalede, istemci ve sunucu arasında güvenli iletişim kurmak için en iyi yöntemler sunarak .NET kullanımı varsayılır. .NET Framework ile ilgili en iyi yöntemler için bkz . .NET Framework ile Aktarım Katmanı Güvenliği (TLS) en iyi yöntemleri.

TLS sürümünü seçin

özelliği aracılığıyla EnabledSslProtocols kullanılacak TLS protokolünün sürümünü belirtmek mümkün olsa da, değeri kullanarak None işletim sistemi ayarlarına ertelemek önerilir (bu varsayılandır).

kararı işletim sistemine ertelemek otomatik olarak kullanılabilir en son TLS sürümünü kullanır ve uygulamanın işletim sistemi yükseltmelerinden sonra değişiklikleri almasını sağlar. İşletim sistemi, artık güvenli olarak kabul edilmeyen TLS sürümlerinin kullanılmasını da engelleyebilir.

Şifreleme paketlerini seçme

SslStream kullanıcıların, TLS el sıkışması sırasında hangi şifreleme paketlerinin kullanılabileceğini CipherSuitesPolicy sınıfı aracılığıyla belirtmesine olanak tanır. TLS sürümlerinde olduğu gibi, işletim sisteminin hangi şifreleme paketleriyle anlaşmak için en iyi olduğunu belirlemesine izin vermeniz önerilir ve bu nedenle kullanmaktan CipherSuitesPolicykaçınması önerilir.

Uyarı

Windows'ta CipherSuitesPolicy desteklenmez ve örnekleme girişimleri NotSupportedException atılmasına neden olur.

Sunucu sertifikası belirtme

Sunucu olarak kimlik doğrulaması yaparken, SslStream bir X509Certificate2 örneği gerektirir. Her zaman özel anahtarı da içeren bir X509Certificate2 örnek kullanmanız önerilir.

Sunucu sertifikasının 'a SslStreamgeçirilebileceği birden çok yol vardır:

Önerilen yaklaşım özelliğini kullanmaktır SslServerAuthenticationOptions.ServerCertificateContext . Diğer iki yoldan biriyle sertifika elde edildiğinde, SslStreamCertificateContext uygulaması tarafından dahili olarak bir SslStream örneği oluşturulur. Bir SslStreamCertificateContext oluşturmak, yoğun CPU kullanan bir işlem olan bir X509Chain oluşturmayı içerir. Bir kez SslStreamCertificateContext oluşturmak ve onu birden çok SslStream örnekler için tekrar kullanmak daha verimlidir.

Örnekleri yeniden SslStreamCertificateContext kullanmak, Linux sunucularında TLS oturumlarının yeniden başlatılması gibi ek özellikleri de etkinleştirir.

Özel X509Certificate doğrulama

Varsayılan sertifika doğrulama yordamının yeterli olmadığı ve bazı özel doğrulama mantığının gerekli olduğu bazı senaryolar vardır. Doğrulama mantığının bölümleri SslClientAuthenticationOptions.CertificateChainPolicy veya SslServerAuthenticationOptions.CertificateChainPolicy belirtilerek özelleştirilebilir. Alternatif olarak, System.Net.Security.SslClientAuthenticationOptions.RemoteCertificateValidationCallback< özelliği aracılığıyla >tamamen özel mantık sağlanabilir. Daha fazla bilgi için Özel sertifika güveni'ne bakın.

Özel sertifika güveni

Makine tarafından güvenilen sertifika yetkililerinden herhangi biri tarafından verilmemiş bir sertifikayla karşılaşıldığında (otomatik olarak imzalanan sertifikalar dahil), varsayılan sertifika doğrulama yordamı başarısız olur. Bunu çözmenin olası yollarından biri, makinenin güvenilir deposuna gerekli sertifika sağlayıcıları eklemektir. Ancak bu, sistemdeki diğer uygulamaları etkileyebilir ve her zaman mümkün değildir.

Alternatif çözüm, X509ChainPolicy aracılığıyla özel güvenilen kök sertifikalarını belirtmektir. Doğrulama sırasında sistem güven listesi yerine kullanılacak özel bir güven listesi belirtmek için aşağıdaki örneği göz önünde bulundurun:

SslClientAuthenticationOptions clientOptions = new();

clientOptions.CertificateChainPolicy = new X509ChainPolicy()
{
    TrustMode = X509ChainTrustMode.CustomRootTrust,
    CustomTrustStore =
    {
        customIssuerCert
    }
};

Önceki ilkeyle yapılandırılan istemciler yalnızca tarafından customIssuerCertgüvenilen sertifikaları kabul eder.

Belirli doğrulama hatalarını yoksay

Kalıcı saati olmayan bir IoT cihazı düşünün. Cihaz açıldığında, saati birkaç yıl öncesine ayarlanır ve bu nedenle tüm sertifikalar "henüz geçerli değil" olarak kabul edilirdi. Geçerlilik süresi ihlallerini göz ardı eden bir doğrulama geri çağırma işlevi uygulamasını gösteren aşağıdaki kodu göz önünde bulundurun.

static bool CustomCertificateValidationCallback(
    object sender,
    X509Certificate? certificate,
    X509Chain? chain,
    SslPolicyErrors sslPolicyErrors)
{
    // Anything that would have been accepted by default is OK
    if (sslPolicyErrors == SslPolicyErrors.None)
    {
        return true;
    }
    
    // If there is something wrong other than a chain processing error, don't trust it.
    if (sslPolicyErrors != SslPolicyErrors.RemoteCertificateChainErrors)
    {
        return false;
    }
    
    Debug.Assert(chain is not null);

    // If the reason for RemoteCertificateChainError is that the chain built empty, don't trust it.
    if (chain.ChainStatus.Length == 0)
    {
        return false;
    }

    foreach (X509ChainStatus status in chain.ChainStatus)
    {
        // If an error other than `NotTimeValid` (or `NoError`) is present, don't trust it.
        if ((status.Status & ~X509ChainStatusFlags.NotTimeValid) != X509ChainStatusFlags.NoError)
        {
            return false;
        }
    }

    return true;
}

Sertifika sabitleme teknikleri

Özel sertifika doğrulamasının gerekli olduğu bir diğer durum da istemcilerin sunucuların belirli bir sertifikayı veya bilinen küçük bir sertifika kümesindeki bir sertifikayı kullanmasını beklemesidir. Bu uygulama sertifika sabitleme olarak bilinir. Aşağıdaki kod parçacığı, sunucunun bilinen belirli bir ortak anahtara sahip bir sertifika sunduğunu denetleyen bir doğrulama geri çağırması gösterir.

static bool CustomCertificateValidationCallback(
    object sender,
    X509Certificate? certificate,
    X509Chain? chain,
    SslPolicyErrors sslPolicyErrors)
{
    // If there is something wrong other than a chain processing error, don't trust it.
    if ((sslPolicyErrors & ~SslPolicyErrors.RemoteCertificateChainErrors) != 0)
    {
        return false;
    }
    
    Debug.Assert(certificate is not null);

    const string ExpectedPublicKey =
        "3082010A0282010100C204ECF88CEE04C2B3D850D57058CC9318EB5C" +
        "A86849B022B5F9959EB12B2C763E6CC04B604C4CEAB2B4C00F80B6B0" +
        "F972C98602F95C415D132B7F71C44BBCE9942E5037A6671C618CF641" +
        "42C546D31687279F74EB0A9D11522621736C844C7955E4D16BE8063D" +
        "481552ADB328DBAAFF6EFF60954A776B39F124D131B6DD4DC0C4FC53" +
        "B96D42ADB57CFEAEF515D23348E72271C7C2147A6C28EA374ADFEA6C" +
        "B572B47E5AA216DC69B15744DB0A12ABDEC30F47745C4122E19AF91B" +
        "93E6AD2206292EB1BA491C0C279EA3FB8BF7407200AC9208D98C5784" +
        "538105CBE6FE6B5498402785C710BB7370EF6918410745557CF9643F" +
        "3D2CC3A97CEB931A4C86D1CA850203010001";

    return certificate.GetPublicKeyString().Equals(ExpectedPublicKey);
}

İstemci sertifikası doğrulaması için dikkat edilmesi gerekenler

Sunucu uygulamalarının, istemci sertifikalarını gerekli hale getirme ve doğrulama sırasında dikkatli olması gerekir. Sertifikalar, veren sertifikanın indirilebileceği yeri belirten AIA (Yetkili Bilgileri Erişimi) uzantısını içerebilir. Sunucu, bu nedenle, istemci sertifikası için X509Chain'yi oluştururken dış sunucudan veren sertifikayı indirmeye çalışabilir. Benzer şekilde, istemci sertifikasının iptal edilmediğinden emin olmak için sunucuların dış sunuculara başvurması gerekebilir.

'yi oluştururken ve doğrularken X509Chain dış sunuculara başvurma ihtiyacı, dış sunucuların yavaş yanıt vermesi durumunda uygulamayı hizmet reddi saldırılarına maruz bırakabilir. Bu nedenle sunucu uygulamaları, X509Chain oluşturma davranışını CertificateChainPolicy ile yapılandırmalıdır.