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

1. نظرة عامة

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

المهام التي ستنفذها

  • استخدام ميزة "منع فقدان البيانات" لفحص السلاسل والملفات بحثًا عن أنواع المعلومات المطابقة
  • التعرّف على تقنيات إخفاء معلومات تحديد الهوية واستخدام ميزة "منع فقدان البيانات" لإخفاء معلومات تحديد الهوية من البيانات
  • كيفية إعادة تحديد هوية البيانات التي تمت إزالة تحديد هويتها باستخدام التشفير مع الحفاظ على التنسيق (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]

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

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

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

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

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

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

يحتوي دليل العيّنات الخاص بالمشروع الذي تم تنزيله في الخطوة السابقة على العديد من ملفات JavaScript التي تستخدم الوظائف المختلفة لخدمة Cloud DLP. ستفحص أداة 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. إخفاء معلومات تحديد الهوية

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

ستوضّح 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);

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

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

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.

لنلقِ نظرة على الدالة التي تعالج إزالة التعريف باستخدام dateshift:

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 هي أداة فعّالة تتيح الوصول إلى منصة قوية لفحص البيانات الحسّاسة وتصنيفها وإخفاء معلومات تحديد الهوية منها.

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

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