Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
TLS (Transport Layer Security) adalah protokol kriptografi yang dirancang untuk mengamankan komunikasi antara dua komputer melalui internet. Protokol TLS diekspos di .NET melalui SslStream kelas .
Artikel ini menyajikan praktik terbaik untuk menyiapkan komunikasi yang aman antara klien dan server dan mengasumsikan penggunaan .NET. Untuk praktik terbaik dengan .NET Framework, lihat Praktik terbaik Keamanan Lapisan Transportasi (TLS) dengan .NET Framework.
Pilih versi TLS
Meskipun dimungkinkan untuk menentukan versi protokol TLS yang akan digunakan melalui properti EnabledSslProtocols, disarankan untuk mengandalkan pengaturan sistem operasi dengan menggunakan nilai None (ini adalah bawaan).
Menuangkan keputusan ke OS secara otomatis menggunakan versi terbaru TLS yang tersedia dan memungkinkan aplikasi mengambil perubahan setelah peningkatan OS. Sistem operasi juga dapat mencegah penggunaan versi TLS yang tidak lagi dianggap aman.
Pilih cipher suite
SslStream memungkinkan pengguna untuk menentukan cipher suite mana yang dapat dinegosiasikan oleh jabat tangan TLS melalui CipherSuitesPolicy kelas . Seperti halnya versi TLS, disarankan untuk membiarkan OS memutuskan cipher suite mana yang terbaik untuk dinegosiasikan dengan, dan, oleh karena itu, disarankan untuk menghindari penggunaan CipherSuitesPolicy.
Nota
CipherSuitesPolicy tidak didukung pada Windows dan upaya untuk membuat instans itu akan menyebabkan NotSupportedException dilemparkan.
Tentukan sertifikat server
Saat mengautentikasi sebagai server, SslStream memerlukan instans X509Certificate2 . Disarankan untuk selalu menggunakan X509Certificate2 instans yang juga berisi kunci privat.
Ada beberapa cara agar sertifikat server dapat diteruskan ke SslStream:
- Langsung sebagai parameter ke SslStream.AuthenticateAsServerAsync atau melalui properti SslServerAuthenticationOptions.ServerCertificate
- Dari panggilan balik pilihan di SslServerAuthenticationOptions.ServerCertificateSelectionCallback properti
- Dengan meneruskan SslStreamCertificateContext dalam properti SslServerAuthenticationOptions.ServerCertificateContext
Pendekatan yang disarankan adalah menggunakan SslServerAuthenticationOptions.ServerCertificateContext properti . Ketika sertifikat diperoleh melalui salah satu dari dua cara lainnya, instans SslStreamCertificateContext dibuat secara internal oleh implementasi SslStream. Membuat SslStreamCertificateContext melibatkan pembangunan X509Chain yang merupakan operasi intensif CPU. Lebih efisien untuk membuat SslStreamCertificateContext sekali dan menggunakannya kembali untuk beberapa SslStream instans.
Menggunakan kembali SslStreamCertificateContext instans juga memungkinkan fitur tambahan seperti penerusan sesi TLS di server Linux.
Validasi kustom X509Certificate
Ada skenario tertentu di mana prosedur validasi sertifikat default tidak memadai dan beberapa logika validasi kustom diperlukan. Bagian dari logika validasi dapat disesuaikan dengan menentukan SslClientAuthenticationOptions.CertificateChainPolicy atau SslServerAuthenticationOptions.CertificateChainPolicy. Atau, logika kustom sepenuhnya dapat disediakan melalui <properti System.Net.Security.SslClientAuthenticationOptions.RemoteCertificateValidationCallback> . Untuk informasi selengkapnya, lihat Kepercayaan sertifikat kustom.
Kepercayaan sertifikat kustom
Saat menemukan sertifikat yang tidak dikeluarkan oleh salah satu otoritas sertifikat yang dipercaya oleh mesin (termasuk sertifikat yang ditandatangani sendiri), prosedur validasi sertifikat default akan gagal. Salah satu cara yang mungkin untuk mengatasinya adalah dengan menambahkan sertifikat penerbit yang diperlukan ke penyimpanan tepercaya komputer. Namun, itu dapat memengaruhi aplikasi lain pada sistem dan tidak selalu memungkinkan.
Solusi alternatifnya adalah menentukan sertifikat akar tepercaya kustom melalui X509ChainPolicy. Untuk menentukan daftar kepercayaan kustom yang akan digunakan alih-alih daftar kepercayaan sistem selama validasi, pertimbangkan contoh berikut:
SslClientAuthenticationOptions clientOptions = new();
clientOptions.CertificateChainPolicy = new X509ChainPolicy()
{
TrustMode = X509ChainTrustMode.CustomRootTrust,
CustomTrustStore =
{
customIssuerCert
}
};
Klien yang dikonfigurasi dengan kebijakan sebelumnya hanya akan menerima sertifikat yang dipercaya oleh customIssuerCert.
Abaikan kesalahan validasi tertentu
Pertimbangkan perangkat IoT tanpa jam persisten. Setelah dinyalakan, jam perangkat akan mulai menunjukkan waktu bertahun-tahun yang lalu, dan oleh karena itu, semua sertifikat akan dianggap "belum valid". Pertimbangkan kode berikut yang menunjukkan implementasi panggilan balik validasi yang mengabaikan pelanggaran periode validitas.
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;
}
Penyematan sertifikat
Situasi lain di mana validasi sertifikat kustom diperlukan adalah ketika klien mengharapkan server untuk menggunakan sertifikat tertentu, atau sertifikat dari sekumpulan kecil sertifikat yang diketahui. Praktik ini dikenal sebagai penyematan sertifikat. Cuplikan kode berikut menunjukkan panggilan balik validasi yang memeriksa apakah server menyajikan sertifikat dengan kunci publik tertentu yang diketahui.
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);
}
Pertimbangan untuk validasi sertifikat klien
Aplikasi server harus berhati-hati saat memerlukan dan memvalidasi sertifikat klien. Sertifikat mungkin berisi ekstensi AIA (Akses Informasi Otoritas) yang menentukan di mana sertifikat penerbit dapat diunduh. Oleh karena itu, server dapat mencoba mengunduh sertifikat penerbit dari server eksternal saat membangun X509Chain untuk sertifikat klien. Demikian pula, server mungkin perlu menghubungi server eksternal untuk memastikan bahwa sertifikat klien belum dicabut.
Kebutuhan untuk menghubungi server eksternal saat membangun dan memvalidasi X509Chain dapat mengekspos aplikasi terhadap penolakan serangan layanan jika server eksternal lambat merespons. Oleh karena itu, aplikasi server harus mengonfigurasi perilaku pembangunan X509Chain menggunakan CertificateChainPolicy.