Обзор предотвращения потери данных в облаке

1. Обзор

Cloud Data Loss Prevention (DLP) — это полностью управляемый сервис, предназначенный для обнаружения, классификации и защиты конфиденциальной информации. В этом практическом занятии мы познакомим вас с некоторыми базовыми возможностями API Cloud DLP и продемонстрируем различные способы его использования для защиты данных.

Что вы будете делать

  • Используйте DLP для проверки строк и файлов на наличие соответствующих типов информации.
  • Узнайте о методах обезличивания данных и используйте DLP для их деидентификации.
  • Узнайте, как повторно идентифицировать обезличенные данные с помощью шифрования с сохранением формата (FPE).
  • Используйте DLP для удаления информации различных типов из строк и изображений.

Что вам понадобится

  • Проект Google Cloud с настроенной системой оплаты. Если у вас его нет, вам придётся его создать .

2. Настройка

Данный практический урок можно полностью выполнить на платформе Google Cloud Platform без какой-либо локальной установки или настройки.

Облачная оболочка

В ходе этого практического занятия мы будем создавать и управлять различными облачными ресурсами и сервисами, используя командную строку через Cloud Shell .

Загрузите репозиторий сопутствующего проекта:

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

После загрузки кода проекта перейдите в каталог samples и установите необходимые пакеты Node.js:

cd samples && npm install

Убедитесь, что вы используете правильный проект, установив его с помощью следующей команды gcloud:

gcloud config set project [PROJECT_ID]

Включить API

Вот API, которые нам нужно будет включить в нашем проекте:

  • API Cloud Data Loss Prevention — предоставляет методы для обнаружения, анализа рисков и обезличивания конфиденциальных фрагментов в тексте, изображениях и хранилищах Google Cloud Platform.
  • API службы управления ключами в облаке (Cloud Key Management Service, KMS) — Google Cloud KMS позволяет клиентам управлять ключами шифрования и выполнять криптографические операции с этими ключами.

Включите необходимые API с помощью следующей команды gcloud:

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

3. Проверьте строки и файлы.

В каталоге samples проекта, загруженного на предыдущем шаге, содержится несколько файлов 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 :

ресурсы/учетные записи.txt

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

Запустите inspect.js еще раз, на этот раз с опцией file:

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

Ниже приведена асинхронная функция, которая использует API для проверки входных данных:

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 может выполнять обезличивание. Обезличивание — это процесс удаления идентифицирующей информации из данных. API обнаруживает конфиденциальные данные, определяемые типами информации, а затем использует преобразование для обезличивания, чтобы замаскировать, удалить или иным образом скрыть эти данные.

deid.js продемонстрирует деидентификацию несколькими способами. Самый простой метод деидентификации — с помощью маски:

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

При использовании маски API заменит символы соответствующего типа информации другим символом, по умолчанию *. Результат будет следующим:

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

Обратите внимание, что адрес электронной почты в строке зашифрован, в то время как произвольный номер заказа остается неизменным. (Возможны пользовательские типы информации, но это выходит за рамки данного руководства).

Рассмотрим функцию, которая использует API DLP для деидентификации с помощью маски:

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);

Деидентификация с помощью шифрования с сохранением формата

API DLP также предоставляет возможность шифрования конфиденциальных данных с помощью криптографического ключа.

Начнём с использования Cloud KMS для создания брелока:

gcloud kms keyrings create dlp-keyring --location global

Теперь мы можем создать ключ, который будем использовать для шифрования данных:

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

API 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 , в свою очередь, используется в запросе к API через функцию 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);

Повторная идентификация данных

Для повторной идентификации данных API 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
) {
...
}

И снова аргументы используются в запросе к API, на этот раз к функции 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]

Это полезно, если вы хотите скрыть конфиденциальную информацию, но при этом определить тип удаляемой информации. API DLP также может удалять информацию из изображений, содержащих текст. Для наглядности рассмотрим пример изображения:

ресурсы/тест.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. Уборка

Мы рассмотрели, как использовать API DLP для маскировки, обезличивания и редактирования конфиденциальной информации в наших данных. Теперь пришло время очистить наш проект от всех созданных нами ресурсов.

Удалить проект

В консоли GCP перейдите на страницу «Менеджер облачных ресурсов» :

В списке проектов выберите проект, над которым мы работали, и нажмите «Удалить» . Вам будет предложено ввести идентификатор проекта. Введите его и нажмите «Завершить».

В качестве альтернативы вы можете удалить весь проект непосредственно из Cloud Shell с помощью gcloud:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

7. Поздравляем!

Ура! Вы это сделали! Cloud DLP — это мощный инструмент, предоставляющий доступ к эффективной платформе для проверки, классификации и обезличивания конфиденциальных данных.

Что мы рассмотрели

  • Мы рассмотрели, как API Cloud DLP можно использовать для проверки строк и файлов на наличие информации различных типов.
  • Мы узнали, как API DLP может обезличивать строки с помощью маски, скрывающей данные, соответствующие типам информации.
  • Мы использовали API DLP для применения ключа шифрования с целью обезличивания, а затем повторной идентификации данных.
  • Мы использовали API DLP для удаления данных из строки, а также из изображения.