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, sınıf aracılığıyla TLS el sıkışması tarafından hangi şifre paketlerinin anlaşabileceğini belirtmesine CipherSuitesPolicy 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.

Not

CipherSuitesPolicy , Windows'ta desteklenmez ve örnek oluşturma girişimleri neden olur NotSupportedException .

Sunucu sertifikası belirtme

Sunucu SslStream olarak kimlik doğrulaması yaparken bir X509Certificate2 örnek gerekir. 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 . Sertifika diğer iki yoldan biri tarafından elde edildiğinde, uygulama tarafından SslStream dahili olarak bir SslStreamCertificateContext örnek oluşturulur. Oluşturma işlemi SslStreamCertificateContext , yoğun CPU kullanan bir işlem olan bir X509Chain oluşturmayı içerir. Bir kez oluşturmak SslStreamCertificateContext ve birden çok SslStream örnek için yeniden 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 veya SslServerAuthenticationOptions.CertificateChainPolicybelirtilerek SslClientAuthenticationOptions.CertificateChainPolicy ö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 bkz . Özel sertifika güveni.

Ö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üvenilen deposuna gerekli veren sertifikaları eklemektir. Ancak bu, sistemdeki diğer uygulamaları etkileyebilir ve her zaman mümkün değildir.

Alternatif çözüm, aracılığıyla X509ChainPolicyözel güvenilen kök sertifikalar 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ı yoksayma

Kalıcı saati olmayan bir IoT cihazı düşünün. Açtıktan sonra, cihazın saati geçmişte uzun yıllar başlar ve bu nedenle tüm sertifikalar "henüz geçerli değil" olarak kabul edilirdi. Geçerlilik süresi ihlallerini yoksayarak doğrulama geri çağırma 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

Ö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. Bu nedenle sunucu, istemci sertifikası için oluştururken dış sunucudan veren sertifikayı X509Chain 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ının X509Chain oluşturma davranışını kullanarak CertificateChainPolicyyapılandırması gerekir.