Applies To.NET

Catatan: Revisi 22 Juni 2023 untuk memperbarui resolusi dan solusi

Catatan: Direvisi 15 Juni 2023 untuk memperbarui opsi 4 dan 5 

Latar belakang

Pada 13 Juni 2023, Microsoft merilis pembaruan keamanan untuk .NET Framework dan .NET yang memengaruhi bagaimana runtime mengimpor sertifikat X.509. Perubahan ini dapat menyebabkan impor sertifikat X.509 melempar CryptographicException dalam skenario di mana impor akan berhasil sebelum pembaruan.

Dokumen ini menjelaskan perubahan dan solusi yang tersedia untuk aplikasi yang terpengaruh.

Perangkat lunak yang terpengaruh

  • .NET Framework 2.0

  • .NET Framework 4.6.2, 4.7, 4.7.1, 4.7.2

  • .NET Framework 4,8

  • .NET Framework 4.8.1

  • .NET 6.0

  • .NET 7.0

API yang Terpengaruh

Deskripsi perubahan

Sebelum 13 Juni 2023, berubah, ketika .NET Framework dan .NET disajikan dengan gumpalan sertifikat biner untuk impor, .NET Framework dan .NET biasanya mendelegasikan validasi dan impor gumpalan ke OS yang mendasarinya. Misalnya, di Windows, .NET Framework dan .NET biasanya mengandalkan API PFXImportCertStore untuk validasi dan impor.

Mulai 13 Juni 2023, berubah, ketika .NET Framework dan .NET disajikan dengan gumpalan sertifikat biner untuk impor, .NET Framework dan .NET akan melakukan validasi tambahan sebelum menyerahkan gumpalan ke OS yang mendasarinya. Validasi tambahan ini melakukan serangkaian pemeriksaan heatistik untuk menentukan apakah sertifikat masuk akan menjadi sumber daya habis yang berbahaya saat diimpor. Karena ini adalah validasi tambahan di luar apa yang biasanya dilakukan OS yang mendasar, ini dapat memblokir gumpalan sertifikat yang akan berhasil diimpor sebelum 13 Juni 2023, berubah.

Regresi yang diketahui

  1. Jika sertifikat X.509 telah diekspor sebagai blob PFX menggunakan jumlah perulangan kata sandi yang sangat tinggi, sertifikat tersebut sekarang mungkin gagal diimpor. Sebagian besar fasilitas ekspor sertifikat menggunakan hitungan perulangan antara 2.000 - 10.000. Setelah pembaruan keamanan diterapkan, impor akan gagal untuk sertifikat yang berisi jumlah perulangan yang lebih besar dari 600.000.

  2. Jika sertifikat X.509 telah diekspor menggunakan kata sandi null [misalnya, melaluiX509Certificate.Export(X509ContentType.Pfx, (string)null)atauX509Certificate.Export(X509ContentType.Pfx)]tanpa kata sandi , sertifikat tersebut sekarang mungkin gagal diimpor.  

    Catatan: Regresi di atas telah diatasi dalam Pembaruan 22 Juni 2023 yang dibahas di KB5028608.

  3. Jika sertifikat X.509 telah diekspor sebagai blob PFX menggunakan kemampuan Windows untuk melindungi kunci privat ke SID, sertifikat tersebut sekarang mungkin gagal diimpor. Hal ini akan memengaruhi blob PFX yang dibuat dengan cara berikut:

    • Melalui Panduan Ekspor Sertifikat Windows dan menentukan dalam panduan bahwa kunci privat harus dilindungi kepada pengguna domain; Atau

    • Melalui cmdlet Ekspor-PfxCertificate PowerShell di mana argumen -ProtectTo eksplisit disediakan; Atau

    • Melalui utilitas sertutil tempat argumen -protectto eksplisit disediakan; Atau

    • Melalui API PFXExportCertStoreEx tempat bendera PKCS12_PROTECT_TO_DOMAIN_SIDS disediakan.

Solusi & Resolusi

Berbagai solusi ada, tergantung pada apakah Anda ingin membuat perubahan bertarget di situs panggilan individual dalam kode Anda, atau Anda ingin mengubah perilaku aplikasi tunggal, atau Anda ingin membuat perubahan di seluruh mesin.

Opsi 1 (pilihan) - Menginstal patch yang diperbarui

Catatan: Ini adalah opsi pilihan karena ini membahas regresi pelanggan yang umum dilaporkan dan tidak memerlukan perubahan kode apa pun pada aplikasi.

Penerapan: Opsi ini berlaku untuk semua versi .NET Framework dan .NET.

Masalah ini telah diatasi dalam Pembaruan 22 Juni 2023 yang dibahas di KB5028608.

Microsoft menyarankan agar pelanggan yang mengalami regresi yang diperkenalkan pada 13 Juni 2023, rilis coba instal patch yang diperbarui ini sebelum mencoba solusi yang tercantum nanti dalam dokumen ini.

Opsi 2 - Memodifikasi situs panggilan

Penerapan: Opsi ini berlaku untuk semua versi .NET Framework dan .NET.

Pertimbangkan apakah blob yang Anda impor dapat dipercaya. Misalnya, apakah gumpalan diambil dari lokasi tepercaya, seperti database atau file konfigurasi di bawah kontrol Anda, atau disediakan melalui permintaan jaringan yang dibuat oleh klien yang tidak diautentikasi atau tidak pantas?

Microsoft sangat menyarankan agar Anda tidak mengimpor blob PFX yang disediakan oleh klien yang tidak diautentikasi atau tidak pantas, karena gumpalan ini dapat berisi perilaku kelelahan sumber daya berbahaya.

Jika anda perlu mengimpor kunci publik sertifikat blob yang diberikan kepada Anda oleh pihak yang tidak tepercaya, Anda bisa menggunakan kode berikut ini untuk mengimpor blob tersebut dengan aman. Kode sampel ini menggunakan metode GetCertContentType untuk menentukan tipe dasar blob sertifikat, dan menolak blob PFX jika Anda hanya berharap untuk mengimpor blob sertifikat kunci publik. KonstruktorX509Certificate2(byte[]) aman untuk digunakan ketika diberikan blob non-PFX yang tidak tepercaya.

using System.Security.Cryptography.X509Certificates;
public static X509Certificate2 ImportPublicCertificateBlob(byte[] blob)
{
     if (X509Certificate2.GetCertContentType(blob) == X509ContentType.Pfx)
    {
          throw new Exception("PFX blobs are disallowed.");
    }
   else
   {
         // Import only after we have confirmed it's not a PFX.
        return new X509Certificate2(blob);
    }
} 

Jika Anda perlu mengimpor blob sertifikat kunci pribadi tanpa kata sandi dan Anda telah menentukan bahwa blob tepercaya, Anda bisa menyembunyikan pemeriksaan validasi tambahan yang dilakukan oleh 13 Juni 2023, rilis keamanan dengan memanggil konstruktor yang berbeda kelebihan beban. Misalnya, Anda bisa memanggil overload konstruktor yang menerima argumen kata sandi string dan melewati null untuk nilai argumen. 

byte[] blobToImport = GetBlobToImport(); // fetch this from a database, config, etc. 

// REGRESSION - byte[] ctor performs additional security checks X509Certificate2 certA = new X509Certificate2(blobToImport);

// RECOMMENDED WORKAROUND - different ctor overload suppresses additional security checks X509Certificate2 certB = new X509Certificate2(blobToImport, (string)null);

Opsi 3 - Memodifikasi atau menyembunyikan validasi tambahan menggunakan variabel lingkungan

Penerapan: Opsi ini hanya berlaku untuk semua versi .NET Framework.  Ini tidak berlaku untuk .NET 6.0+.

Meskipun .NET Framework secara default membatasi operasi impor untuk mengambil tidak lebih dari 600.000 perulangan kata sandi, batas ini dapat dikonfigurasi secara luas aplikasi atau mesin dengan menggunakan variabel lingkungan. Batas baru ini akan berlaku untuk semua panggilan API Terpengaruh yang tercantum di atas.

Untuk mengubah batas, atur variabel lingkunganCOMPlus_Pkcs12UnspecifiedPasswordIterationLimitke nilai batas baru. Misalnya, untuk menetapkan batasan ke 1.000.000 (satu juta) perulangan, atur variabel lingkungan seperti yang diperlihatkan di bawah ini.

  • Angka ini mengontrol batas perulangan total , yang merupakan jumlah hitungan perulangan MAC, konten aman terenkripsi, dan jumlah perulangan tas yang diselimuti. Jika Anda telah mengekspor PFX secara manual menggunakan hitungan perulangan eksplisit <iter_count> (misalnya, melalui openssl pkcs12 -export -iter <iter_count>) dan ingin mengimpor blob PFX tersebut, atur variabel lingkungan ini ke nilai setidaknya sebesar jumlah semua perulangan yang diharapkan. Dalam praktiknya, .NET Framework dan .NET dapat memungkinkan jumlah perulangan total sedikit melebihi batas eksplisit yang dikonfigurasi di sini.

COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=1000000

Untuk menyembunyikan pemeriksaan tambahan sepenuhnya, atur variabel lingkungan ke nilai sentinel khusus -1, seperti yang diperlihatkan di bawah ini.

  • ⚠️ Peringatan: Hanya atur nilai variabel lingkungan ke -1 jika Anda yakin bahwa aplikasi target tidak menangani input sertifikat yang tidak tepercaya.

COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=-1

Opsi 4 - Memodifikasi atau menyembunyikan validasi tambahan menggunakan AppContext

Penerapan: Opsi ini berlaku untuk .NET 6.0+saja.  Ini tidak berlaku untuk .NET Framework

Meskipun .NET secara default membatasi operasi impor untuk mengambil tidak lebih dari 600.000 perulangan kata sandi, batas ini dapat dikonfigurasi di seluruh aplikasi dengan menggunakan sakelar AppContext. Batas baru ini akan berlaku untuk semua panggilan API Terpengaruh yang tercantum di atas.

Untuk mengubah batas, atur sakelar AppContext System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit ke nilai batas baru. Misalnya, untuk mengatur batas ke 1.000.000 (satu juta) perulangan, atur sakelar seperti yang diperlihatkan di bawah ini.

  • Angka ini mengontrol batas perulangan total, yang merupakan jumlah hitungan perulangan MAC, konten aman terenkripsi, dan jumlah perulangan tas yang diselimuti. Jika Anda telah mengekspor PFX secara manual menggunakan hitungan perulangan eksplisit <iter_count> (misalnya, melalui openssl pkcs12 -export -iter <iter_count>) dan ingin mengimpor blob PFX tersebut, atur variabel lingkungan ini ke nilai setidaknya sebesar jumlah semua perulangan yang diharapkan. Dalam praktiknya, .NET dapat memungkinkan jumlah perulangan total sedikit melebihi batas eksplisit apa pun yang dikonfigurasi di sini.

Untuk mengatur sakelar dalam file proyek aplikasi Anda (.csproj atau .vbproj):

<!--

  • This switch only works if the current project file represents an application. It has no effect if the current project file represents a shared library.

-->

<ItemGroup>

  • <RuntimeHostConfigurationOption Include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" Value="1000000" />

</ItemGroup>

Atau, Anda dapat menempatkan file bernama runtimeconfig.template.json dengan konten berikut dalam direktori yang sama yang berisi file proyek aplikasi Anda:

{

     "configProperties": {

  • "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": 1000000

      }

}

Untuk informasi selengkapnya tentang mengubah pengaturan konfigurasi runtime .NET, lihat halaman dokumentasi .NET Pengaturan konfigurasi runtime.

Untuk menyembunyikan pemeriksaan tambahan sepenuhnya, atur sakelar konfigurasi nilai sentinel khusus -1, seperti yang diperlihatkan di bawah ini.

⚠️ Peringatan: Hanya atur sakelar AppContext ke -1 jika Anda yakin bahwa aplikasi target tidak menangani input sertifikat yang tidak tepercaya.

Dalam file proyek aplikasi (.csproj atau .vbproj):

<!--

  • This switch only works if the current project file represents an application. It has no effect if the current project file represents a shared library.

-->

<ItemGroup>

  • <RuntimeHostConfigurationOption Include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" Value="-1" />

</ItemGroup>

Atau dalam file runtimeconfig.template.json:

{

  • "configProperties": { 
  •     "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": -1

     }

}

Opsi 5 - Memodifikasi atau menyembunyikan lebar mesin validasi tambahan melalui registri (Khusus Windows untuk .NET Framework)

Penerapan: Opsi ini hanya berlaku untuk semua versi .NET Framework.  Ini tidak berlaku untuk .NET 6.0+.

Meskipun .NET Framework secara default membatasi operasi impor untuk mengambil tidak lebih dari 600.000 perulangan kata sandi, batas ini dapat dikonfigurasi selebar mesin dengan menggunakan registri HKLM. Batas baru ini akan berlaku untuk semua panggilan API Terpengaruh yang tercantum di atas.

Untuk mengubah batas, di bawah kunci registriHKLM\Software\Microsoft\.NETFramework, atur nilaiPkcs12UnspecifiedPasswordIterationLimitke batas baru. Misalnya, untuk mengatur batas ke 1.000.000 (satu juta) perulangan, jalankan perintah seperti yang diperlihatkan di bawah ini dari prompt perintah yang ditinggikan.

  • Angka ini mengontrol batas perulangan total , yang merupakan jumlah hitungan perulangan MAC, konten aman terenkripsi, dan jumlah perulangan tas yang diselimuti. Jika Anda telah mengekspor PFX secara manual menggunakan hitungan perulangan eksplisit <iter_count> (misalnya, melalui openssl pkcs12 -export -iter <iter_count>) dan ingin mengimpor gumpalan PFX tersebut, atur nilai registri ini ke nilai setidaknya sebesar jumlah semua perulangan yang diharapkan. Dalam praktiknya, .NET Framework memungkinkan jumlah perulangan total sedikit melebihi batas eksplisit yang dikonfigurasi di sini.

  • Pengaturan registri bergantung pada arsitektur. Untuk memastikan bahwa aplikasi mengamati nilai yang Anda konfigurasi terlepas dari arsitektur targetnya, ingatlah untuk mengubah registri 32-bit dan 64-bit, seperti yang diperlihatkan di bawah ini.

reg add "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /t REG_DWORD /d 1000000 /reg:32 reg add "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /t REG_DWORD /d 1000000 /reg:64

Untuk menyembunyikan pemeriksaan tambahan sepenuhnya, atur nilai registri ke -1 dari prompt perintah yang ditinggikan, seperti yang diperlihatkan di bawah ini.

  • ⚠️ Peringatan: Hanya atur nilai registri ke -1 jika Anda yakin bahwa layanan yang berjalan pada mesin target tidak menangani input sertifikat yang tidak tepercaya.

  • Untuk mengatur sentinel -1, gunakan tipe REG_SZ, bukan tipe REG_DWORD. Pengaturan registri bergantung pada arsitektur. Untuk memastikan bahwa aplikasi mengamati nilai yang Anda konfigurasi terlepas dari arsitektur targetnya, ingatlah untuk mengubah registri 32-bit dan 64-bit, seperti yang diperlihatkan di bawah ini.

reg add "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /t REG_SZ /d -1 /reg:32 reg add "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /t REG_SZ /d -1 /reg:64

Untuk mengembalikan perubahan registri, hapus nilai registry Pkcs12UnspecifiedPasswordIterationLimit dari prompt perintah yang ditingkatkan.

reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:32 reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:64

Catatan khusus Windows

Di Windows, .NET Framework mengimpor sertifikat melalui fungsi PFXImportCertStore. Fungsi ini melakukan validasinya sendiri, termasuk menempatkan batasnya sendiri pada jumlah perulangan maksimum blob PFX yang diperbolehkan. Pemeriksaan ini masih akan dilakukan setelah PFX diimpor. Tje. Variabel lingkungan khusus NET dan kunci registri yang dijelaskan di atas tidak memengaruhi bagaimana PFXImportCertStore melakukan pemeriksaan ini.

Perlu bantuan lainnya?

Ingin opsi lainnya?

Jelajahi manfaat langganan, telusuri kursus pelatihan, pelajari cara mengamankan perangkat Anda, dan banyak lagi.

Komunitas membantu Anda bertanya dan menjawab pertanyaan, memberikan umpan balik, dan mendengar dari para ahli yang memiliki pengetahuan yang luas.