استخدم التشفير من جانب العميل مع ميزة Always Encrypted لقاعدة بيانات Azure Cosmos DB

ينطبق على: NoSQL

هام

تم إدخال تغيير فاصل مع الإصدار 1.0 من حزم التشفير الخاصة بنا. إذا أنشأت مفاتيح تشفير البيانات والحاويات الممكّنة للتشفير بإصدارات سابقة، فستحتاج إلى إعادة إنشاء قواعد البيانات والحاويات بعد ترحيل رمز العميل إلى حزم 1.0.

Always Encrypted هي ميزة مصممة لحماية البيانات الحساسة، مثل أرقام بطاقات الائتمان أو أرقام الهوية الوطنية/الإقليمية (على سبيل المثال، أرقام الضمان الاجتماعي في الولايات المتحدة)، المخزنة في Azure Cosmos DB. تتيح ميزة Always Encrypted للعملاء تشفير البيانات الحساسة داخل تطبيقات العميل، وعدم الكشف عن مفاتيح التشفير لقاعدة البيانات.

توفر ميزة Always Encrypted إمكانات التشفير من جانب العميل إلى قاعدة بيانات Azure Cosmos. يمكن أن يكون تشفير البيانات من جانب العميل مطلوبًا في السيناريوهات التالية:

  • حماية البيانات الحساسة التي لها خصائص سرية محددة: تسمح Always Encrypted للعملاء بتشفير البيانات الحساسة داخل تطبيقاتهم ولا تكشف أبدا عن بيانات النص العادي أو مفاتيح التشفير لخدمة Azure Cosmos DB.
  • تنفيذ التحكم في الوصول لكل خاصية: نظرا لأنه يتم التحكم في التشفير باستخدام المفاتيح التي تمتلكها وتديرها من Azure Key Vault، يمكنك تطبيق نهج الوصول للتحكم في الخصائص الحساسة التي يمكن لكل عميل الوصول إليها.

المفاهيم

تقدم ميزة Always Encrypted لقاعدة بيانات Azure Cosmos بعض المفاهيم الجديدة التي يتم تضمينها في تكوين التشفير من جانب العميل.

مفاتيح التشفير

مفاتيح تشفير البيانات

عند استخدام ميزة Always Encrypted، يتم تشفير البيانات بمفاتيح تشفير البيانات (DEK) التي ينبغي إنشاؤها مسبقًا. يتم تخزين DEKs في خدمة قاعدة بيانات Azure Cosmos، ويتم تحديدها على مستوى قاعدة البيانات؛ بحيث يمكن مشاركة DEK عبر حاويات متعددة. إنشاء DEKs من جانب العميل باستخدام قاعدة بيانات Azure Cosmos SDK.

يمكنك:

  • إنشاء DEK واحدًا لكل خاصية للتشفير، أو
  • استخدم نفس DEK لتشفير خصائص متعددة.

المفاتيح التي يديرها العميل

قبل تخزين DEKs في قاعدة بيانات Azure Cosmos، يتم تغليفها بواسطة مفتاح يديره العميل (CMK). من خلال التحكم في التفاف وفك تغليف أجهزة DEK، تتحكم CMK بشكل فعال في الوصول إلى البيانات التي تم تشفيرها باستخدام DEKs المقابلة لها. تم تصميم تخزين CMK كإطار قابل للتوسيع، مع تطبيق افتراضي يتوقع تخزينها في Azure Key Vault.

مفاتيح التشفير

نهج التشفير

على غرار نهج الفهرسة، نهج التشفير هو مواصفات على مستوى الحاوية تصف كيفية تشفير خصائص JSON. ينبغي توفير هذا النهج عند إنشاء الحاوية وهي غير قابلة للتغيير. في الإصدار الحالي، لا يمكنك تحديث نهج التشفير.

لكل خاصية تريد تشفيرها، تحدد سياسة التشفير:

  • مسار الخاصية في شكل /property. المسارات ذات المستوى الأعلى فقط مدعومة حاليا، المسارات المتداخلة مثل /path/to/property غير مدعومة.
  • معرف DEK لاستخدامه عند تشفير وفك تشفير الخاصية.
  • نوع التشفير. قد تكون إما عشوائية أو حتمية.
  • خوارزمية التشفير المراد استخدامها عند تشفير الخاصية. يمكن للخوارزمية المحددة تجاوز الخوارزمية المحددة عند إنشاء المفتاح إذا كانت متوافقة.

التشفير العشوائي مقابل التشفير المحدد

لا تتعرف خدمة قاعدة بيانات Azure Cosmos أبدًا على النص العادي للخصائص المشفرة باستخدام ميزة Always Encrypted. ومع ذلك، لا يزال يدعم بعض إمكانات الاستعلام عن البيانات المشفرة، اعتمادًا على نوع التشفير المستخدم للخاصية. تدعم ميزة Always Encrypted نوعي التشفير التاليين:

  • يقومالتشفير الحتمي دائماً بإنشاء نفس القيمة المشفرة لأي قيمة نص عادي معينة. يسمح استخدام التشفير المحدد للاستعلامات بأداء عوامل تصفية المساواة على الخصائص المشفرة. ومع ذلك، قد يسمح للمهاجمين بتخمين المعلومات حول القيم المشفرة من خلال فحص الأنماط في الخاصية المشفرة. وينطبق هذا بشكل خاص في حال كان هناك مجموعة صغيرة من القيم المشفرة المحتملة؛ مثل: True/ False، أو المنطقة الشمالية/ الجنوبية/ الشرقية/ الغربية.

  • يستخدم التشفير العشوائي أسلوباً يقوم على تشفير البيانات بطريقة أقل قابلية للتنبؤ. إن التشفير العشوائي أكثر أمانًا؛ ولكنه يمنع الاستعلامات من التصفية على الخصائص المشفرة.

راجع إنشاء متجه التهيئة (IV) لمعرفة المزيد حول التشفير المحدد والعشوائي في Always Encrypted.

إعداد Azure Key Vault

الخطوة الأولى لبدء استخدام Always Encrypted هي إنشاء CMK في Azure Key Vault:

  1. إنشاء مثيل Azure Key Vault جديد، أو استعرض للوصول إلى مثيل موجود.
  2. إنشاء مفتاح جديد في قسم المفاتيح .
  3. بمجرد إنشاء المفتاح، استعرض إلى نسخته الحالية، وانسخ معرف مفتاحه الكامل:
    https://<my-key-vault>.vault.azure.net/keys/<key>/<version>. في حال حذفت إصدار المفتاح في نهاية معرف المفتاح، فسيتم استخدام أحدث إصدار من المفتاح.

بعد ذلك، ستحتاج إلى تكوين كيفية وصول قاعدة بياناتAzure Cosmos SDK إلى مثيل Azure Key Vault. تتم هذه المصادقة من خلال هوية Microsoft Entra. على الأرجح، ستستخدم هوية تطبيق Microsoft Entra أو هوية مدارة كوكيل بين التعليمات البرمجية للعميل ومثيل Azure Key Vault، على الرغم من إمكانية استخدام أي نوع من الهوية. استخدم الخطوات التالية لاستخدام هوية Microsoft Entra كوكيل:

  1. من مثيل Azure Key Vault، انتقل إلى قسم نُهج الوصول، وأضف نهجاً جديداً:

    1. في أذونات المفتاح، حدد Get و List و Unwrap Key و Wrap Key و Verify و Sign.
    2. في Select principal، ابحث عن هوية Microsoft Entra.

حماية CMK من الحذف العرضي

للتأكد من عدم فقدان الوصول إلى بياناتك المشفرة بعد الحذف العرضي ل CMK، يوصى بتعيين خاصيتين على مثيل Azure Key Vault: Soft Delete و Purge Protection.

إذا قمت بإنشاء مثيل Azure Key Vault جديد، فقم بتمكين هذه الخصائص أثناء الإنشاء:

لقطة شاشة لخصائص الحماية من الحذف المبدئي والإزالة لمثيل Azure Key Vault جديد.

إذا كنت تستخدم مثيل Azure Key Vault الحالي، فيمكنك التحقق من تمكين هذه الخصائص من خلال الاطلاع على قسم الخصائص في مدخل Microsoft Azure. إذا لم يتم تمكين أي من هذه الخصائص، فراجع قسمي "تمكين الحذف الناعم" و"تمكين الحماية من التطهير" في إحدى المقالات التالية:

تهيئة SDK

إشعار

إن ميزة Always Encrypted لقاعدة بيانات Azure Cosmos مدعومة حاليًا.

  • في .NET مع حزمة Microsoft.Azure.Cosmos.Encryption.
  • في Java مع حزمة azure.cosmos.encryption.

لاستخدام ميزة Always Encrypted، يجب إرفاق مثيل لـ KeyResolver بمثيل Azure Cosmos DB SDK. تُستخدم هذه الفئة، المحددة في مساحة الاسم Azure.Security.KeyVault.Keys.Cryptography، للتفاعل مع مخزن المفاتيح الذي يستضيف CMK.

تستخدم DefaultAzureCredential القصاصات البرمجية التالية الفئة لاسترداد هوية Microsoft Entra لاستخدامها عند الوصول إلى مثيل Azure Key Vault. يمكنك العثور على أمثلة لإنشاء أنواع مختلفة من TokenCredential الفئات هنا.

إشعار

ستحتاج حزمة Azure.Identity إضافية للوصول إلى الفئات TokenCredential.

var tokenCredential = new DefaultAzureCredential();
var keyResolver = new KeyResolver(tokenCredential);
var client = new CosmosClient("<connection-string>")
    .WithEncryption(keyResolver, KeyEncryptionKeyResolverName.AzureKeyVault);

إنشاء مفتاح تشفير البيانات

قبل أن يمكن تشفير البيانات في حاوية، يجب إنشاء مفتاح تشفير البيانات في قاعدة البيانات الأصل.

يتم إنشاء مفتاح جديد لتشفير البيانات عن طريق استدعاء الأسلوب CreateClientEncryptionKeyAsync وتمريره:

  • معرّف سلسلة يعرّف المفتاح في قاعدة البيانات بشكل فريد.
  • تهدف خوارزمية التشفير إلى استخدامها مع المفتاح. يتم دعم خوارزمية واحدة فقط حاليًا.
  • معرف المفتاح ل CMK المخزن في Azure Key Vault. يتم تمرير هذه المعلمة في كائن عام EncryptionKeyWrapMetadata حيث:
    • يحدد type نوع محلل المفاتيح (على سبيل المثال، Azure Key Vault).
    • يمكن أن يكون name أي اسم مألوف تريده.
    • يجب أن يكون value هو معرف المفتاح.

    هام

    بمجرد إنشاء المفتاح، استعرض إلى نسخته الحالية، وانسخ معرّف مفتاحه الكامل:https://<my-key-vault>.vault.azure.net/keys/<key>/<version>. في حال حذفت إصدار المفتاح في نهاية معرف المفتاح، فسيتم استخدام أحدث إصدار من المفتاح.

    • يحدد algorithm الخوارزمية التي يجب استخدامها لتضمين مفتاح تشفير المفتاح بالمفتاح الذي يديره العميل.
var database = client.GetDatabase("my-database");
await database.CreateClientEncryptionKeyAsync(
    "my-key",
    DataEncryptionAlgorithm.AeadAes256CbcHmacSha256,
    new EncryptionKeyWrapMetadata(
        KeyEncryptionKeyResolverName.AzureKeyVault,
        "akvKey",
        "https://<my-key-vault>.vault.azure.net/keys/<key>/<version>",
        EncryptionAlgorithm.RsaOaep.ToString()));

إنشاء حاوية باستخدام نهج التشفير

حدد نهج التشفير على مستوى الحاوية عند إنشاء الحاوية.

var path1 = new ClientEncryptionIncludedPath
{
    Path = "/property1",
    ClientEncryptionKeyId = "my-key",
    EncryptionType = EncryptionType.Deterministic.ToString(),
    EncryptionAlgorithm = DataEncryptionAlgorithm.AeadAes256CbcHmacSha256
};
var path2 = new ClientEncryptionIncludedPath
{
    Path = "/property2",
    ClientEncryptionKeyId = "my-key",
    EncryptionType = EncryptionType.Randomized.ToString(),
    EncryptionAlgorithm = DataEncryptionAlgorithm.AeadAes256CbcHmacSha256
};
await database.DefineContainer("my-container", "/partition-key")
    .WithClientEncryptionPolicy()
    .WithIncludedPath(path1)
    .WithIncludedPath(path2)
    .Attach()
    .CreateAsync();

قراءة وكتابة البيانات المشفرة

كيفية تشفير البيانات

عندما تتم كتابة مستند إلى قاعدة بيانات Azure Cosmos تبحث SDK عن نهج التشفير لمعرفة الخصائص التي ينبغي تشفيرها، وكيفية ذلك. نتيجة التشفير هو سلسلة 64 الأساسية.

تشفير الأنواع المعقدة:

  • عندما تكون الخاصية المراد تشفيرها عبارة عن مصفوفة JSON، يتم تشفير كل إدخال من المصفوفة.

  • عندما تكون الخاصية المراد تشفيرها عبارة عن عنصر JSON، يتم تشفير القيم الطرفية للعنصر فقط. تظل أسماء الخصائص الفرعية الوسيطة في شكل نص عادي.

قراءة العناصر المشفرة

لا يلزم اتخاذ أي إجراء صريح لفك تشفير الخصائص المشفرة عند إصدار قراءات النقاط (جلب عنصر واحد بواسطة المعرف، ومفتاح القسم)، أو الاستعلامات، أو قراءة موجز التغيير. ذلك لأن:

  • تبحث SDK عن نهج التشفير لمعرفة الخصائص التي ينبغي فك تشفيرها.
  • تدمج نتيجة التشفير نوع JSON الأصلي للقيمة.

لاحظ أن دقة الخصائص المشفرة وفك تشفيرها اللاحق يعتمدان فقط على النتائج التي يتم إرجاعها من طلباتك. على سبيل المثال، إذا تم property1 تشفيره ولكن تم إسقاطه في property2 (SELECT property1 AS property2 FROM c)، فلن يتم تعريفه كخاصية مشفرة عند استلامه بواسطة SDK.

استعلامات التصفية على الخصائص المشفرة

عند كتابة استعلامات تقوم بتصفية الخصائص المشفرة، ويجب استخدام طريقة معينة لتمرير قيمة معلمة الاستعلام. يأخذ هذا الأسلوب الوسيطات التالية:

  • اسم معلمة الاستعلام.
  • القيمة المطلوب استخدامها في الاستعلام.
  • مسار الخاصية المشفرة (كما هو محدد في نهج التشفير).

هام

يمكن استخدام الخصائص المشفرة فقط في عوامل تصفية المساواة (WHERE c.property = @Value). أي استخدام آخر سيعود بمجموعة نتائج استعلام غير متوقعة وخاطئة. سيتم فرض هذا القيد بشكل أفضل في الإصدارات التالية من SDK.

var queryDefinition = container.CreateQueryDefinition(
    "SELECT * FROM c where c.property1 = @Property1");
await queryDefinition.AddParameterAsync(
    "@Property1",
    1234,
    "/property1");

قراءة المستندات عندما لا يمكن فك تشفير سوى مجموعة فرعية من الخصائص

في الحالات التي لا يمتلك فيها العميل حق الوصول إلى جميع CMK المستخدمة لتشفير الخصائص، يمكن فقط فك تشفير مجموعة فرعية من الخصائص عند إعادة قراءة البيانات. على سبيل المثال، إذا property1 تم تشفيره باستخدام key1 وتم property2 تشفيره باستخدام key2، فإن تطبيق العميل الذي لديه حق الوصول إلى key1 فقط يمكنه قراءة البيانات، ولكن ليس property2. في مثل هذه الحالة، يجب قراءة بياناتك من خلال استعلامات SQL وإسقاط الخصائص التي لا يمكن للعميل فك تشفيرها: SELECT c.property1, c.property3 FROM c.

دوران CMK

قد ترغب في "تدوير" CMK (أي استخدام CMK جديد بدلاً من الحالي) في حال كنت تشك في تعرض CMK الحالي للاختراق. من الممارسات الأمنية الشائعة أيضًا تدوير CMK بانتظام. لإجراء هذا الدوران، ما عليك سوى توفير معرف المفتاح لـ CMK الجديد الذي ينبغي استخدامه لتغليف DEK معين. لاحظ أن هذه العملية لا تؤثر على تشفير بياناتك؛ بل تؤثر على حماية DEK. لا ينبغي إبطال الوصول إلى CMK السابق حتى اكتمال الاستدارة.

await database.RewrapClientEncryptionKeyAsync(
    "my-key",
    new EncryptionKeyWrapMetadata(
        KeyEncryptionKeyResolverName.AzureKeyVault,
        "akvKey",
        "https://<my-key-vault>.vault.azure.net/keys/<new-key>/<version>",
        EncryptionAlgorithm.RsaOaep.ToString()));

تدوير مفتاح التشفير DEK

لا يتم تقديم تدوير مفتاح تشفير البيانات كإمكانية تسليم المفتاح. هذا لأن تحديث مفتاح التشفير DEK يتطلب مسحاً لجميع الحاويات حيث يتم استخدام هذا المفتاح وإعادة تشفير جميع الخصائص المشفرة باستخدام هذا المفتاح. يمكن أن تحدث هذه العملية فقط من جانب العميل لأن خدمة Azure Cosmos DB لا تخزن أو تصل إلى قيمة النص العادي لمفتاح التشفير DEK.

في الممارسة العملية، يمكن إجراء دوران مفتاح التشفير DEK عن طريق إجراء ترحيل البيانات من الحاويات المتأثرة إلى الحاويات الجديدة. يمكن إنشاء الحاويات الجديدة بنفس الطريقة تماماً مثل الحاويات الأصلية. لمساعدتك في ترحيل البيانات، يمكنك العثور على أداة ترحيل مستقلة على GitHub.

إضافة خصائص مشفرة إضافية

لا يتم دعم إضافة خصائص مشفرة إضافية إلى نهج تشفير موجودة للأسباب نفسها الموضحة في القسم أعلاه. تتطلب هذه العملية فحصاً كاملاً للحاوية للتأكد من أن جميع مثيلات الخصائص مشفرة بشكل صحيح، وهذه عملية يمكن أن تحدث فقط من جانب العميل. تماماً مثل تدوير مفتاح التشفير DEK، يمكن إضافة خصائص مشفرة إضافية عن طريق إجراء ترحيل البيانات إلى حاوية جديدة باستخدام نهج تشفير مناسبة.

إذا كانت لديك مرونة في طريقة إضافة الخصائص المشفرة الجديدة من وجهة نظر المخطط، فيمكنك أيضاً الاستفادة من الطبيعة الحيادية للمخطط لـ Azure Cosmos DB. إذا كنت تستخدم خاصية محددة في نهج التشفير الخاصة بك على أنها "حقيبة خصائص"، يمكنك إضافة المزيد من الخصائص أدناه بدون قيود. على سبيل المثال، دعنا نتخيل أن property1 تم تعريفه في نهج التشفير الخاصة بك وأنك تكتب في البداية property1.property2 في مستنداتك. إذا احتجت، في مرحلة لاحقة، إلى إضافة property3 كخاصية مشفرة، فيمكنك البدء في كتابة property1.property3 في مستنداتك وسيتم تشفير الخاصية الجديدة تلقائياً أيضاً. هذا الأسلوب لا يتطلب أي ترحيل البيانات.

الخطوات التالية