نظرة عامة على منع فقدان البيانات من Cloud

1. نظرة عامة

ميزة "منع فقدان البيانات" (DLP) في السحابة الإلكترونية هي خدمة مُدارة بالكامل تم تصميمها للمساعدة في اكتشاف المعلومات الحسّاسة وتصنيفها وحمايتها. سيقدّم هذا الدرس التطبيقي حول الترميز بعض الإمكانات الأساسية لواجهة برمجة تطبيقات Cloud DLP، وسيوضّح الطرق المختلفة التي يمكن استخدامها لحماية البيانات.

الأنشطة

  • استخدام ميزة "منع فقدان البيانات" لفحص السلاسل والملفات بحثًا عن أنواع المعلومات المطابقة
  • تعرَّف على أساليب إخفاء معلومات تحديد الهوية واستخدام ميزة "منع فقدان البيانات" لإخفاء هوية البيانات.
  • تعرَّف على كيفية إعادة تحديد البيانات التي تم إخفاء هويتها باستخدام التشفير الذي يحافظ على التنسيق (FPE).
  • استخدام ميزة "منع فقدان البيانات" لإخفاء أنواع المعلومات من السلاسل والصور

المتطلبات

  • مشروع على Google Cloud تم إعداد الفوترة فيه وإذا لم يكن لديك حساب، عليك إنشاء حساب.

2. بدء الإعداد

يمكن تشغيل هذا الدرس التطبيقي بالكامل على Google Cloud Platform بدون أي عمليات تثبيت أو ضبط على الجهاز.

Cloud Shell

خلال هذا الدرس التطبيقي، سنعمل على توفير الخدمات والموارد المختلفة للسحابة الإلكترونية وإدارتها باستخدام سطر الأوامر عبر Cloud Shell.

تنزيل مستودع المشروع المصاحب:

git clone https://github.com/googleapis/nodejs-dlp

بعد تنزيل رمز المشروع، انتقِل إلى دليل النماذج وثبِّت حِزم Node.js المطلوبة:

cd samples && npm install

تأكَّد من استخدام المشروع الصحيح من خلال ضبطه باستخدام الأمر gcloud التالي:

gcloud config set project [PROJECT_ID]

تفعيل واجهات برمجة التطبيقات

في ما يلي واجهات برمجة التطبيقات التي نحتاج إلى تفعيلها في مشروعنا:

  • واجهة برمجة التطبيقات لمنع فقدان البيانات في السحابة الإلكترونية: توفّر طرقًا لرصد الأجزاء الحسّاسة للخصوصية في النصوص والصور ومستودعات تخزين Google Cloud Platform وتحليلها وإخفاء معلومات تحديد الهوية فيها.
  • واجهة برمجة تطبيقات خدمة إدارة المفاتيح (KMS) في السحابة الإلكترونية: تتيح خدمة Google Cloud KMS للعملاء إدارة مفاتيح التشفير وتنفيذ عمليات التشفير باستخدام تلك المفاتيح.

فعِّل واجهات برمجة التطبيقات المطلوبة باستخدام الأمر gcloud التالي:

gcloud services enable dlp.googleapis.com cloudkms.googleapis.com \
--project ${GOOGLE_CLOUD_PROJECT}

3- فحص السلاسل والملفات

يحتوي دليل نماذج المشروع الذي تم تنزيله في الخطوة السابقة على العديد من ملفات JavaScript التي تستخدم الوظائف المختلفة لميزة "منع فقدان البيانات" في السحابة الإلكترونية. سيفحص inspect.js السلسلة أو الملف المقدَّم بحثًا عن أنواع المعلومات الحسّاسة.

لاختبار ذلك، يمكنك تقديم الخيار string ونموذج سلسلة تتضمّن بعض المعلومات التي يُحتمل أن تكون حسّاسة:

node inspect.js -c $GOOGLE_CLOUD_PROJECT \
string 'My email address is jenny@somedomain.com and you can call me at 555-867-5309'

يجب أن تُطلعنا النتائج على النتائج لكلّ نوع من أنواع المعلومات المتطابقة، بما في ذلك:

اقتباس: يحدد النموذج

InfoType: نوع المعلومات الذي تم رصده لذلك الجزء من السلسلة. تتوفر هنا قائمة كاملة بأنواع المعلومات المحتملة. بشكل تلقائي، لن يفحص inspect.js إلا أنواع المعلومات CREDIT_CARD_NUMBER وPHONE_NUMBER وEMAIL_ADDRESS فقط.

الاحتمالية: يتم تصنيف النتائج استنادًا إلى مدى احتمالية تمثيل كل منها للمطابقة. يمكن أن تتراوح الاحتمالية بين VERY_UNLIKELY وVERY_LIKELY.

نتائج طلب الأمر أعلاه هي:

Findings:
        Quote: jenny@somedomain.com
        Info type: EMAIL_ADDRESS
        Likelihood: LIKELY
        Quote: 555-867-5309
        Info type: PHONE_NUMBER
        Likelihood: VERY_LIKELY

وبالمثل، يمكننا فحص الملفات لتحديد أنواع المعلومات. يمكنك الاطّلاع على نموذج ملف accounts.txt:

resources/accounts.txt

My credit card number is 1234 5678 9012 3456, and my CVV is 789.

شغِّل inspect.js مرة أخرى، ولكن هذه المرة باستخدام خيار الملف:

node inspect.js -c $GOOGLE_CLOUD_PROJECT file resources/accounts.txt

النتائج:

Findings:
        Quote: 5678 9012 3456
        Info type: CREDIT_CARD_NUMBER
        Likelihood: VERY_LIKELY

بالنسبة لأي نوع من طلبات البحث، يمكننا تحديد النتائج حسب الاحتمالية أو نوع المعلومات. على سبيل المثال:

node inspect.js -c $GOOGLE_CLOUD_PROJECT \
string 'Call 900-649-2568 or email me at anthony@somedomain.com' \
-m VERY_LIKELY

من خلال تحديد VERY_LIKELY على أنّه الحد الأدنى للاحتمال، يتم استبعاد أي مطابقات أقل من VERY_LIKELY:

Findings:
        Quote: 900-649-2568
        Info type: PHONE_NUMBER
        Likelihood: VERY_LIKELY

ستكون النتائج الكاملة بدون قيد هي:

Findings:
        Quote: 900-649-2568
        Info type: PHONE_NUMBER
        Likelihood: VERY_LIKELY
        Quote: anthony@somedomain.com
        Info type: EMAIL_ADDRESS
        Likelihood: LIKELY

وبالمثل، يمكننا تحديد نوع المعلومات التي نتحقق منها:

node inspect.js -c $GOOGLE_CLOUD_PROJECT \
string 'Call 900-649-2568 or email me at anthony@somedomain.com' \
-t EMAIL_ADDRESS

ولا يتم عرض سوى نوع المعلومات المحدّد في حال العثور على:

Findings:
        Quote: anthony@somedomain.com
        Info type: EMAIL_ADDRESS
        Likelihood: LIKELY

في ما يلي الدالة غير المتزامنة التي تستخدم واجهة برمجة التطبيقات لفحص الإدخال:

inspect.js

async function inspectString(
  callingProjectId,
  string,
  minLikelihood,
  maxFindings,
  infoTypes,
  customInfoTypes,
  includeQuote
) {
...
}

تُستخدم الوسيطات المقدمة للمعلمات أعلاه لإنشاء كائن طلب. بعد ذلك، يتم تقديم هذا الطلب إلى الدالة inspectContent للحصول على استجابة تؤدي إلى الناتج:

inspect.js

  // Construct item to inspect
  const item = {value: string};

  // Construct request
  const request = {
    parent: dlp.projectPath(callingProjectId),
    inspectConfig: {
      infoTypes: infoTypes,
      customInfoTypes: customInfoTypes,
      minLikelihood: minLikelihood,
      includeQuote: includeQuote,
      limits: {
        maxFindingsPerRequest: maxFindings,
      },
    },
    item: item,
  };
...
...
 const [response] = await dlp.inspectContent(request);

4. إخفاء الهوية

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

سيُظهر deid.js إخفاء معلومات تحديد الهوية بعدة طرق. أبسط طريقة لإخفاء الهوية هي باستخدام القناع:

node deid.js deidMask -c $GOOGLE_CLOUD_PROJECT \
"My order number is F12312399. Email me at anthony@somedomain.com"

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

My order number is F12312399. Email me at *****************************

لاحِظ أنّ عنوان البريد الإلكتروني في السلسلة مُشوَّش بينما يكون رقم الطلب العشوائي سليمًا. (يمكن استخدام أنواع معلومات مخصّصة، ولكنها خارج نطاق هذا الدرس التطبيقي حول الترميز).

لنرَ الدالة التي تستخدم واجهة برمجة تطبيقات "منع فقدان البيانات" لتحديد الهوية بالقناع:

deid.js

async function deidentifyWithMask(
  callingProjectId,
  string,
  maskingCharacter,
  numberToMask
) {
...
}

ومرة أخرى، يتم استخدام هذه الوسيطات لإنشاء كائن طلب. ويتم توفيرها هذه المرة للدالة deidentifyContent:

deid.js

  // Construct deidentification request
  const item = {value: string};
  const request = {
    parent: dlp.projectPath(callingProjectId),
    deidentifyConfig: {
      infoTypeTransformations: {
        transformations: [
          {
            primitiveTransformation: {
              characterMaskConfig: {
                maskingCharacter: maskingCharacter,
                numberToMask: numberToMask,
              },
            },
          },
        ],
      },
    },
    item: item,
  };
... 
... 
const [response] = await dlp.deidentifyContent(request);

إلغاء تحديد الهوية باستخدام ترميز "الحفاظ على التنسيق"

توفر واجهة برمجة تطبيقات منع فقدان البيانات أيضًا إمكانية تشفير قيم البيانات الحساسة باستخدام مفتاح تشفير.

سنبدأ باستخدام Cloud KMS لإنشاء سلسلة مفاتيح:

gcloud kms keyrings create dlp-keyring --location global

يمكننا الآن إنشاء مفتاح سنستخدمه لتشفير البيانات:

gcloud kms keys create dlp-key \
--purpose='encryption' \
--location=global \
--keyring=dlp-keyring

ستقبل واجهة برمجة التطبيقات DLP مفتاحًا مُشفَّرًا باستخدام مفتاح KMS الذي أنشأناه. يمكننا إنشاء سلسلة عشوائية سيتم التفافها. سنحتاج إلى هذا لاحقًا لإعادة تحديد ما يلي:

export AES_KEY=`head -c16 < /dev/random | base64 -w 0`

يمكننا الآن تشفير السلسلة باستخدام مفتاح KMS. سيؤدي هذا إلى إنشاء ملف ثنائي يحتوي على السلسلة المشفرة كنص مشفر:

echo -n $AES_KEY | gcloud kms encrypt \
--location global \
--keyring dlp-keyring  \
--key dlp-key \
--plaintext-file - \
--ciphertext-file ./ciphertext.bin 

باستخدام deid.js، يمكننا الآن إخفاء هوية رقم الهاتف في السلسلة النموذجية أدناه باستخدام التشفير:

node deid.js deidFpe -c $GOOGLE_CLOUD_PROJECT \
"My client's cell is 9006492568" `base64 -w 0 ciphertext.bin` \
projects/${GOOGLE_CLOUD_PROJECT}/locations/global/keyRings/dlp-keyring/cryptoKeys/dlp-key \
-s PHONE_NUMBER

سيعرض المخرج السلسلة التي تحتوي على أنواع المعلومات المطابقة التي يتم استبدالها بسلسلة مشفرة ويسبقها نوع المعلومات المشار إليه بالعلامة -s:

My client's cell is PHONE_NUMBER(10):vSt55z79nR

لنلقِ نظرة على الدالة التي نستخدمها لإلغاء تحديد السلسلة:

deid.js

async function deidentifyWithFpe(
  callingProjectId,
  string,
  alphabet,
  surrogateType,
  keyName,
  wrappedKey
) {
...
}

تُستخدَم الوسيطات لإنشاء كائن cryptoReplaceFfxFpeConfig:

deid.js

  const cryptoReplaceFfxFpeConfig = {
    cryptoKey: {
      kmsWrapped: {
        wrappedKey: wrappedKey,
        cryptoKeyName: keyName,
      },
    },
    commonAlphabet: alphabet,
  };
  if (surrogateType) {
    cryptoReplaceFfxFpeConfig.surrogateInfoType = {
      name: surrogateType,
    };
  }

وبالتالي، يتم استخدام الكائن cryptoReplaceFfxFpeConfig في الطلب الموجّه إلى واجهة برمجة التطبيقات من خلال الدالة deidentifyContent:

deid.js

  // Construct deidentification request
  const item = {value: string};
  const request = {
    parent: dlp.projectPath(callingProjectId),
    deidentifyConfig: {
      infoTypeTransformations: {
        transformations: [
          {
            primitiveTransformation: {
              cryptoReplaceFfxFpeConfig: cryptoReplaceFfxFpeConfig,
            },
          },
        ],
      },
    },
    item: item,
  };

  try {
    // Run deidentification request
    const [response] = await dlp.deidentifyContent(request);

إعادة تحديد البيانات

لإعادة تحديد البيانات، ستستخدم واجهة برمجة تطبيقات منع فقدان البيانات النص المُشفَّر الذي أنشأناه في الخطوة السابقة:

node deid.js reidFpe -c $GOOGLE_CLOUD_PROJECT \
"<YOUR_DEID_OUTPUT>" \
PHONE_NUMBER `base64 -w 0 ciphertext.bin`  \
projects/${GOOGLE_CLOUD_PROJECT}/locations/global/keyRings/dlp-keyring/cryptoKeys/dlp-key

سيكون الناتج هو السلسلة الأصلية بدون تحديد نوع بديل أو نوع محدَّد:

My client's cell is 9006492568

الدالة المستخدمة لإعادة تحديد البيانات مشابهة للدالة المستخدمة لإخفاء تحديدها:

deid.js

async function reidentifyWithFpe(
  callingProjectId,
  string,
  alphabet,
  surrogateType,
  keyName,
  wrappedKey
) {
...
}

ومرة أخرى، يتم استخدام الوسيطات في طلب واجهة برمجة التطبيقات، ولكن هذه المرة في الدالة reidentifyContent:

deid.js

  // Construct deidentification request
  const item = {value: string};
  const request = {
    parent: dlp.projectPath(callingProjectId),
    reidentifyConfig: {
      infoTypeTransformations: {
        transformations: [
          {
            primitiveTransformation: {
              cryptoReplaceFfxFpeConfig: {
                cryptoKey: {
                  kmsWrapped: {
                    wrappedKey: wrappedKey,
                    cryptoKeyName: keyName,
                  },
                },
                commonAlphabet: alphabet,
                surrogateInfoType: {
                  name: surrogateType,
                },
              },
            },
          },
        ],
      },
    },
    inspectConfig: {
      customInfoTypes: [
        {
          infoType: {
            name: surrogateType,
          },
          surrogateType: {},
        },
      ],
    },
    item: item,
  };

  try {
    // Run reidentification request
    const [response] = await dlp.reidentifyContent(request);

إلغاء تحديد التواريخ باستخدام ميزة "تغيير التواريخ"

في سياقات معينة، يمكن اعتبار التواريخ بيانات حساسة قد نرغب في التشويش عليها. يتيح لنا تغيير التاريخ تغيير التواريخ بمقدار عشوائي مع الحفاظ على تسلسل الفترة الزمنية ومدتها. يتم تغيير كل تاريخ في مجموعة من خلال مقدار الوقت الفريد لهذا الإدخال. لتوضيح إخفاء تحديد الهوية من خلال تغيير التاريخ، ألقِ أولاً نظرة على نموذج ملف CSV الذي يحتوي على بيانات التاريخ:

resources/dates.csv

name,birth_date,register_date,credit_card
Ann,01/01/1980,07/21/1996,4532908762519852
James,03/06/1988,04/09/2001,4301261899725540
Dan,08/14/1945,11/15/2011,4620761856015295
Laura,11/03/1992,01/04/2017,4564981067258901

تحتوي البيانات على حقلَين يمكننا تطبيق التغيير في التاريخ عليهما: birth_date وregister_date. سيقبل deid.js قيمة الحد الأدنى وقيمة الحد الأعلى لتحديد نطاق لتحديد عدد عشوائي من اليوم لتغيير التواريخ:

node deid.js deidDateShift -c $GOOGLE_CLOUD_PROJECT resources/dates.csv datesShifted.csv 30 90 birth_date

سيتم إنشاء ملف باسم datesShifted.csv مع تغيير التواريخ عشوائيًا بين 30 و90 يومًا. في ما يلي مثال على الناتج الذي تم إنشاؤه:

name,birth_date,register_date,credit_card
Ann,2/6/1980,7/21/1996,4532908762519852
James,5/18/1988,4/9/2001,4301261899725540
Dan,9/16/1945,11/15/2011,4620761856015295
Laura,12/16/1992,1/4/2017,4564981067258901

لاحظ أننا تمكنا أيضًا من تحديد عمود التاريخ في ملف CSV الذي أردنا نقله. الحقل birth_date: يبقى الحقل register_date بدون تغيير.

لنلقِ نظرة على الدالة التي تعالج عملية إخفاء معلومات تحديد الهوية باستخدام ميزة "التحكّم بالتاريخ":

deid.js

async function deidentifyWithDateShift(
  callingProjectId,
  inputCsvFile,
  outputCsvFile,
  dateFields,
  lowerBoundDays,
  upperBoundDays,
  contextFieldId,
  wrappedKey,
  keyName
) {
...
}

يُرجى العلم أنّ هذه الدالة يمكن أن تقبل مفتاحًا ملفوفًا واسمًا رئيسيًا، على غرار إخفاء تحديد الهوية من خلال FPE، وذلك كي يتوفّر لدينا خيار توفير مفتاح تشفير لإعادة تحديد متغيّر التاريخ. تستخدم الوسيطات التي نقدمها لإنشاء كائن dateShiftConfig:

deid.js

  // Construct DateShiftConfig
  const dateShiftConfig = {
    lowerBoundDays: lowerBoundDays,
    upperBoundDays: upperBoundDays,
  };

  if (contextFieldId && keyName && wrappedKey) {
    dateShiftConfig.context = {name: contextFieldId};
    dateShiftConfig.cryptoKey = {
      kmsWrapped: {
        wrappedKey: wrappedKey,
        cryptoKeyName: keyName,
      },
    };
  } else if (contextFieldId || keyName || wrappedKey) {
    throw new Error(
      'You must set either ALL or NONE of {contextFieldId, keyName, wrappedKey}!'
    );
  }

  // Construct deidentification request
  const request = {
    parent: dlp.projectPath(callingProjectId),
    deidentifyConfig: {
      recordTransformations: {
        fieldTransformations: [
          {
            fields: dateFields,
            primitiveTransformation: {
              dateShiftConfig: dateShiftConfig,
            },
          },
        ],
      },
    },
    item: tableItem,
  };

5- إخفاء السلاسل والصور

هناك طريقة أخرى لإخفاء المعلومات الحسّاسة، وهي إخفاء المحتوى. سيتم استبدال المطابقة بنوع المعلومات الذي تم تحديده للمطابقة معه. توضيح:redact.js

node redact.js -c $GOOGLE_CLOUD_PROJECT \
string "Please refund the purchase to my credit card 4012888888881881" \
-t 'CREDIT_CARD_NUMBER'

يستبدل الناتج نموذج رقم بطاقة الائتمان بنوع المعلومات CREDIT_CARD_NUMBER:

Please refund the purchase on my credit card [CREDIT_CARD_NUMBER]

ويكون هذا الإجراء مفيدًا إذا أردت إخفاء معلومات حساسة مع الاستمرار في تحديد نوع المعلومات التي تتم إزالتها. يمكن أيضًا لواجهة برمجة تطبيقات منع فقدان البيانات إخفاء المعلومات من الصور التي تحتوي على نص. للتوضيح، نلقِ نظرة على نموذج صورة:

resources/test.png

bf3719cfeb5676ff.png

لإخفاء رقم الهاتف وعنوان البريد الإلكتروني من الصورة أعلاه:

node redact.js -c $GOOGLE_CLOUD_PROJECT \
image resources/test.png ./redacted.png \
-t PHONE_NUMBER -t EMAIL_ADDRESS

كما هو محدّد، سيتم إنشاء صورة جديدة باسم redacted.png مع حجب المعلومات المطلوبة:

ce023dd95cccc40f.png

فيما يلي الدالة المستخدمة للإخفاء من سلسلة:

redact.js

async function redactText(
  callingProjectId, 
  string,
  minLikelihood,
  infoTypes
) {
...}

إليك الطلب الذي سيتم تقديمه إلى الدالة deidentifyContent:

redact.js

const request = {
    parent: dlp.projectPath(callingProjectId),
    item: {
      value: string,
    },
    deidentifyConfig: {
      infoTypeTransformations: {
        transformations: [replaceWithInfoTypeTransformation],
      },
    },
    inspectConfig: {
      minLikelihood: minLikelihood,
      infoTypes: infoTypes,
    },
  };

وبالمثل، في ما يلي دالة إخفاء الصورة:

redact.js

async function redactImage(
  callingProjectId,
  filepath,
  minLikelihood,
  infoTypes,
  outputPath
) {
...}

إليك الطلب الذي سيتم تقديمه إلى الدالة redactImage:

redact.js

// Construct image redaction request
  const request = {
    parent: dlp.projectPath(callingProjectId),
    byteItem: {
      type: fileTypeConstant,
      data: fileBytes,
    },
    inspectConfig: {
      minLikelihood: minLikelihood,
      infoTypes: infoTypes,
    },
    imageRedactionConfigs: imageRedactionConfigs,
  };

6- تَنظيم

لقد استكشفنا كيف يمكننا استخدام واجهة برمجة التطبيقات لمنع فقدان البيانات لإخفاء المعلومات الحساسة من بياناتنا وإخفاء معلومات تحديد محتواها. حان الوقت الآن لتنظيف مشروعنا من أي موارد أنشأناها.

حذف المشروع

في وحدة تحكّم Google Cloud Platform، انتقِل إلى صفحة Cloud Resource Manager:

في قائمة المشاريع، اختَر المشروع الذي بدأنا العمل فيه وانقر على حذف. سيُطلب منك كتابة رقم تعريف المشروع. أدخِله وانقر على إيقاف التشغيل.

بدلاً من ذلك، يمكنك حذف المشروع بأكمله مباشرةً من Cloud Shell باستخدام gcloud:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

7. تهانينا!

رائع! أحسنت. ميزة "منع فقدان البيانات في السحابة الإلكترونية" هي أداة فعّالة توفّر إمكانية الوصول إلى منصة فعّالة لفحص البيانات الحسّاسة وتصنيفها وإخفاء معلومات تحديد الهوية فيها.

المواضيع التي تناولناها

  • رأينا كيف يمكن استخدام Cloud DLP API لفحص السلاسل والملفات لأنواع معلومات متعدّدة.
  • تعلّمنا كيف يمكن لواجهة برمجة تطبيقات DLP DLP تحديد السلاسل باستخدام قناع لإخفاء أنواع المعلومات المُطابقة للبيانات.
  • استخدمنا "واجهة برمجة التطبيقات لمنع فقدان البيانات" لاستخدام مفتاح تشفير لإخفاء البيانات ثم إعادة تحديدها
  • استخدمنا واجهة برمجة التطبيقات "منع فقدان البيانات" لإخفاء البيانات من سلسلة بالإضافة إلى صورة