ملاحظه: تمت مراجعته في 22 يونيو 2023 لتحديث الحل والحلول البديلة
ملاحظه: تمت مراجعته في 15 يونيو 2023 لتحديث الحل البديل للخيارين 4 و5
الخلفيه
في 13 يونيو 2023، أصدرت Microsoft تحديث أمان إلى .NET Framework و.NET يؤثر على كيفية استيراد وقت التشغيل لشهادات X.509. قد تتسبب هذه التغييرات في طرح استيراد شهادة X.509 CryptographicException في السيناريوهات التي كان من الممكن أن ينجح فيها الاستيراد قبل التحديث.
يصف هذا المستند التغيير والحلول المتاحة للتطبيقات المتأثرة.
البرامج المتأثرة
-
.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
واجهات برمجة التطبيقات المتأثرة
وصف التغيير
قبل 13 يونيو 2023، قم بالتغيير، عندما يتم تقديم .NET Framework و.NET مع كائن ثنائي كبير الحجم للشهادة للاستيراد، .NET Framework و.NET عادة ما يفوض التحقق من صحة الكائن الثنائي كبير الحجم واستيراده إلى نظام التشغيل الأساسي. على سبيل المثال، في Windows، يعتمد .NET Framework و.NET عادة على واجهة برمجة تطبيقات PFXImportCertStore للتحقق من الصحة والاستيراد.
اعتبارا من 13 يونيو 2023، قم بالتغيير، عند تقديم .NET Framework و.NET مع blob شهادة ثنائية للاستيراد، سيقوم .NET Framework و.NET في بعض الحالات بإجراء تحقق إضافي قبل تسليم الكائن الثنائي كبير الحجم إلى نظام التشغيل الأساسي. يقوم هذا التحقق الإضافي بإجراء سلسلة من الفحوصات الإرشادية لتحديد ما إذا كانت الشهادة الواردة ستستنفد الموارد بشكل ضار عند الاستيراد. نظرا لأن هذا تحقق إضافي يتجاوز ما سينفذه نظام التشغيل الأساسي عادة، فقد يمنع تغيير الكائنات الثنائية كبيرة الحجم للشهادة التي كانت ستستورد بنجاح قبل 13 يونيو 2023.
الانحدارات المعروفة
-
إذا تم تصدير شهادة X.509 ككائن ثنائي كبير الحجم PFX باستخدام عدد تكرار كلمة مرور مرتفع بشكل غير شائع، فقد تفشل هذه الشهادة الآن في الاستيراد. تستخدم معظم مرافق تصدير الشهادات عدد التكرار في مكان ما بين 2000 - 10000. بعد تطبيق تحديث الأمان، سيفشل الاستيراد للشهادات التي تحتوي على عدد تكرار أكبر من 600,000.
-
إذا تم تصدير شهادة X.509 باستخدام كلمة مرور فارغة [على سبيل المثال، عبرX509Certificate.Export(X509ContentType.Pfx, (string)null)أوX509Certificate.Export(X509ContentType.Pfx)]بدون كلمة مرور ، فقد تفشل هذه الشهادة الآن في الاستيراد.
ملاحظة: تمت معالجة الانحدار أعلاه في تحديث 22 يونيو 2023 الذي تمت مناقشته في KB5028608.
-
إذا تم تصدير شهادة X.509 ككائن ثنائي كبير الحجم PFX باستخدام قدرة Windows على حماية المفتاح الخاص إلى SID، فقد تفشل هذه الشهادة الآن في الاستيراد. سيؤثر هذا على الكائنات الثنائية كبيرة الحجم PFX التي تم إنشاؤها بالطريقة التالية:
-
عبر معالج تصدير الشهادات في Windows وتحديد في المعالج أنه يجب حماية المفتاح الخاص لمستخدم مجال؛ او
-
عبر Cmdlet Export-PfxCertificate من PowerShell حيث يتم توفير وسيطة -ProtectTo صريحة؛ او
-
عبر الأداة المساعدة certutil حيث يتم توفير وسيطة -protectto صريحة؛ او
-
عبر واجهة برمجة تطبيقات PFXExportCertStoreEx حيث يتم توفير علامة PKCS12_PROTECT_TO_DOMAIN_SIDS.
-
الحل & الحلول البديلة
توجد حلول بديلة مختلفة، اعتمادا على ما إذا كنت تريد إجراء تغييرات مستهدفة على مواقع المكالمات الفردية داخل التعليمات البرمجية الخاصة بك، أو تريد تغيير سلوك تطبيق واحد، أو تريد إجراء تغييرات على مستوى الجهاز.
الخيار 1 (المفضل) - تثبيت تصحيح محدث
ملاحظة: هذا هو الخيار المفضل لأنه يعالج تراجعات العملاء التي تم الإبلاغ عنها بشكل شائع ولا يتطلب أي تغييرات في التعليمات البرمجية للتطبيق.
القابلية للتطبيق: ينطبق هذا الخيار على جميع إصدارات .NET Framework و.NET.
تمت معالجة هذه المشكلة في تحديث 22 يونيو 2023 الذي تمت مناقشته في KB5028608.
توصي Microsoft العملاء الذين يواجهون تراجعات تم تقديمها في 13 يونيو 2023، بإصدار محاولة تثبيت هذا التصحيح المحدث قبل محاولة الحلول البديلة المدرجة لاحقا في هذا المستند.
الخيار 2 - تعديل موقع المكالمة
القابلية للتطبيق: ينطبق هذا الخيار على جميع إصدارات .NET Framework و.NET.
ضع في اعتبارك ما إذا كان الكائن الثنائي كبير الحجم الذي تستورده جديرا بالثقة. على سبيل المثال، هل تم استرداد الكائن الثنائي كبير الحجم من موقع موثوق به، مثل قاعدة بيانات أو ملف تكوين تحت سيطرتك، أم تم توفيره عبر طلب شبكة تم إجراؤه بواسطة عميل غير مصادق عليه أو غير متميز؟
توصي Microsoft بشدة بعدم استيراد الكائنات الثنائية كبيرة الحجم PFX المقدمة لك من قبل عملاء غير مصادق عليهم أو غير متميزين، حيث يمكن أن تحتوي هذه الكائنات الثنائية كبيرة الحجم على سلوكيات استنفاد الموارد الضارة.
إذا كنت بحاجة إلى استيراد كائن ثنائي كبير الحجم لشهادة مفتاح عام تم منحه لك من قبل طرف غير موثوق به، يمكنك استخدام التعليمات البرمجية التالية لاستيراد مثل هذا الكائن الثنائي كبير الحجم بأمان. يستخدم نموذج التعليمات البرمجية هذا أسلوب GetCertContentType لتحديد النوع الأساسي لكائن ثنائي كبير الحجم للشهادة، ويرفض الكائنات الثنائية كبيرة الحجم PFX في الحالات التي تتوقع فيها فقط استيراد كائن ثنائي كبير الحجم لشهادة المفتاح العام. الدالة الإنشائيةX509Certificate2(byte[]) آمنة للاستخدام عند إعطاء كائنات ثنائية كبيرة الحجم غير موثوق بها غير PFX.
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);
}
}
إذا كنت بحاجة إلى استيراد كائن ثنائي كبير الحجم لشهادة مفتاح خاص بدون كلمة مرور وقررت أن الكائن الثنائي كبير الحجم جدير بالثقة، يمكنك منع عمليات التحقق الإضافية التي تم إجراؤها بواسطة إصدار الأمان في 13 يونيو 2023 عن طريق استدعاء تحميل زائد لمنشئ مختلف. على سبيل المثال، يمكنك استدعاء المنشئ التحميل الزائد الذي يقبل وسيطة كلمة مرور سلسلة وتمرير فارغ لقيمة الوسيطة.
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);
الخيار 3 - تعديل أو منع التحقق الإضافي باستخدام متغير بيئة
القابلية للتطبيق: ينطبق هذا الخيار على جميع إصدارات .NET Framework فقط. لا ينطبق على .NET 6.0+.
بينما .NET Framework بشكل افتراضي الحد من عمليات الاستيراد إلى ما لا يزيد عن 600000 تكرار لكلمة مرور، يمكن تكوين هذا الحد على أساس على مستوى التطبيق أو على مستوى الجهاز باستخدام متغير بيئة. سيتم تطبيق هذا الحد الجديد على جميع استدعاءات واجهات برمجة التطبيقات المتأثرة المذكورة أعلاه.
لتغيير الحد، قم بتعيين متغير البيئةCOMPlus_Pkcs12UnspecifiedPasswordIterationLimitإلى قيمة ما يجب أن يكون عليه الحد الجديد. على سبيل المثال، لتعيين الحد إلى 1000000 (مليون) تكرار، قم بتعيين متغير البيئة كما هو موضح أدناه.
-
يتحكم هذا الرقم في الحد الإجمالي للتكرار، وهو مجموع عدد تكرارات MAC والمحتويات الآمنة المشفرة وعدد تكرار الحقيبة المكفنة. إذا قمت بتصدير PFX يدويا باستخدام عدد تكرار صريح <iter_count> (على سبيل المثال، عبر openssl pkcs12 -export -iter <iter_count>) وترغب في استيراد كائن ثنائي كبير الحجم PFX هذا، فقم بتعيين متغير البيئة هذا إلى قيمة كبيرة على الأقل مثل مجموع جميع التكرارات المتوقعة. في الممارسة العملية، قد يسمح .NET Framework و.NET لتجاوز إجمالي عدد التكرارات قليلا أي حد صريح تم تكوينه هنا.
COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=1000000
لمنع عمليات التحقق الإضافية بالكامل، قم بتعيين متغير البيئة إلى قيمة sentinel الخاصة -1، كما هو موضح أدناه.
-
⚠️ تحذير: قم بتعيين قيمة متغير البيئة إلى -1 فقط إذا كنت متأكدا من أن التطبيق الهدف لا يتعامل مع إدخال الشهادة غير الموثوق به.
COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=-1
الخيار 4 - تعديل أو منع التحقق الإضافي باستخدام AppContext
القابلية للتطبيق: ينطبق هذا الخيار على .NET 6.0+only. لا ينطبق على .NET Framework
بينما يحد .NET بشكل افتراضي من عمليات الاستيراد لا تستغرق أكثر من 600000 تكرار لكلمة مرور، يمكن تكوين هذا الحد على مستوى التطبيق باستخدام مفتاح AppContext. سيتم تطبيق هذا الحد الجديد على جميع استدعاءات واجهات برمجة التطبيقات المتأثرة المذكورة أعلاه.
لتغيير الحد، قم بتعيين مفتاح تبديل AppContext System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit إلى قيمة ما يجب أن يكون عليه الحد الجديد. على سبيل المثال، لتعيين الحد إلى 1000000 (مليون) تكرار، قم بتعيين التبديل كما هو موضح أدناه.
-
يتحكم هذا الرقم في الحد الإجمالي للتكرار، وهو مجموع عدد تكرارات MAC والمحتويات الآمنة المشفرة وعدد تكرار الحقيبة المكفنة. إذا قمت بتصدير PFX يدويا باستخدام عدد تكرار صريح <iter_count> (على سبيل المثال، عبر openssl pkcs12 -export -iter <iter_count>) وترغب في استيراد كائن ثنائي كبير الحجم PFX هذا، فقم بتعيين متغير البيئة هذا إلى قيمة كبيرة على الأقل مثل مجموع جميع التكرارات المتوقعة. في الممارسة العملية، قد يسمح .NET لتجاوز إجمالي عدد التكرارات قليلا أي حد صريح تم تكوينه هنا.
لتعيين المفتاح داخل ملف مشروع التطبيق الخاص بك (.csproj أو .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>
بدلا من ذلك، يمكنك وضع ملف يسمى runtimeconfig.template.json بالمحتويات التالية في نفس الدليل الذي يحتوي على ملف مشروع التطبيق الخاص بك:
{
"configProperties": {
- "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": 1000000
}
}
لمزيد من المعلومات حول تغيير إعدادات تكوين وقت تشغيل .NET، راجع صفحة الوثائق إعدادات تكوين وقت تشغيل .NET.
لمنع عمليات التحقق الإضافية بالكامل، قم بتعيين تبديل التكوين لقيمة sentinel الخاصة -1، كما هو موضح أدناه.
⚠️ تحذير: قم بتعيين مفتاح AppContext إلى -1 فقط إذا كنت متأكدا من أن التطبيق الهدف لا يتعامل مع إدخال الشهادة غير الموثوق به.
داخل ملف مشروع التطبيق (.csproj أو .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>
أو ضمن ملف runtimeconfig.template.json:
{
- "configProperties": {
- "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": -1
}
}
الخيار 5 - تعديل أو منع جهاز التحقق الإضافي على مستوى الجهاز عبر السجل (Windows فقط .NET Framework)
القابلية للتطبيق: ينطبق هذا الخيار على جميع إصدارات .NET Framework فقط. لا ينطبق على .NET 6.0+.
بينما .NET Framework بشكل افتراضي الحد من عمليات الاستيراد إلى ما لا يزيد عن 600,000 تكرار لكلمة مرور، يمكن تكوين هذا الحد على مستوى الجهاز باستخدام سجل HKLM. سيتم تطبيق هذا الحد الجديد على جميع استدعاءات واجهات برمجة التطبيقات المتأثرة المذكورة أعلاه.
لتغيير الحد، ضمن مفتاح التسجيلHKLM\Software\Microsoft\.NETFramework، قم بتعيين القيمةPkcs12UnspecifiedPasswordIterationLimitإلى ما يجب أن يكون عليه الحد الجديد. على سبيل المثال، لتعيين الحد إلى 1000000 (مليون) تكرار، قم بتشغيل الأوامر كما هو موضح أدناه من موجه أوامر غير مقيد.
-
يتحكم هذا الرقم في الحد الإجمالي للتكرار، وهو مجموع عدد تكرارات MAC والمحتويات الآمنة المشفرة وعدد تكرار الحقيبة المكفنة. إذا قمت بتصدير PFX يدويا باستخدام عدد تكرار صريح <iter_count> (على سبيل المثال، عبر openssl pkcs12 -export -iter <iter_count>) وترغب في استيراد كائن PFX الثنائي كبير الحجم هذا، فقم بتعيين قيمة التسجيل هذه إلى قيمة كبيرة على الأقل مثل مجموع جميع التكرارات المتوقعة. في الممارسة العملية، قد تسمح .NET Framework لتجاوز إجمالي عدد التكرارات قليلا أي حد صريح تم تكوينه هنا.
-
يعتمد إعداد التسجيل على البنية. للتأكد من أن التطبيقات تراقب القيمة التي تم تكوينها بغض النظر عن بنيتها المستهدفة، تذكر تعديل كل من السجلات 32 بت و64 بت، كما هو موضح أدناه.
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
لمنع عمليات التحقق الإضافية بالكامل، قم بتعيين قيمة التسجيل إلى -1 من موجه أوامر غير مقيد، كما هو موضح أدناه.
-
⚠️ تحذير: قم بتعيين قيمة التسجيل إلى -1 فقط إذا كنت متأكدا من أن الخدمات التي تعمل على الجهاز الهدف لا تتعامل مع إدخال الشهادة غير الموثوق به.
-
لتعيين -1 sentinel، استخدم نوع REG_SZ بدلا من نوع REG_DWORD. يعتمد إعداد التسجيل على البنية. للتأكد من أن التطبيقات تراقب القيمة التي تم تكوينها بغض النظر عن بنيتها المستهدفة، تذكر تعديل كل من السجلات 32 بت و64 بت، كما هو موضح أدناه.
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
لإعادة تغييرات السجل، احذف قيمة السجل Pkcs12UnspecifiedPasswordIterationLimit من موجه أوامر غير مقيد.
reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:32 reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:64
ملاحظات خاصة ب Windows
في Windows، .NET Framework استيراد الشهادات من خلال الدالة PFXImportCertStore. تقوم هذه الدالة بإجراء التحقق من الصحة الخاص بها، بما في ذلك وضع حدودها الخاصة على الحد الأقصى لعدد التكرار المسموح به في PFX. ستظل هذه الفحوصات تتم عند استيراد PFX. . لا تؤثر متغيرات البيئة الخاصة ب NET ومفاتيح التسجيل الموضحة أعلاه على كيفية تنفيذ PFXImportCertStore لهذه الفحوصات.