Omówienie usługi Cloud Data Loss Prevention

1. Omówienie

Cloud Data Loss Prevention (DLP) to w pełni zarządzana usługa ułatwiająca wykrywanie, klasyfikowanie i ochronę informacji poufnych. W ramach tych ćwiczeń w Codelabs przedstawimy niektóre podstawowe możliwości interfejsu Cloud DLP API i pokażemy różne sposoby jego wykorzystania do ochrony danych.

Co trzeba zrobić

  • Używanie DLP do sprawdzania ciągów znaków i plików pod kątem pasujących typów informacji
  • Poznaj techniki deidentyfikacji i używaj DLP do deidentyfikacji danych
  • Dowiedz się, jak ponownie zidentyfikować dane, które zostały poddane deidentyfikacji za pomocą szyfrowania z zachowaniem formatu (FPE)
  • Usuwanie typów informacji z ciągów znaków i obrazów za pomocą DLP

Czego potrzebujesz

  • Projekt Google Cloud ze skonfigurowanymi płatnościami. Jeśli nie masz konta Google, musisz je utworzyć.

2. Przygotowanie

To ćwiczenia w Codelabs można wykonać w całości w Google Cloud Platform bez konieczności lokalnej instalacji ani konfiguracji.

Cloud Shell

W ramach tych ćwiczeń w programie udostępnimy różne zasoby i usługi w chmurze oraz będziemy nimi zarządzać za pomocą wiersza poleceń w Cloud Shell.

Pobierz repozytorium projektów towarzyszących:

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

Po pobraniu kodu projektu przejdź do katalogu przykładów i zainstaluj wymagane pakiety Node.js:

cd samples && npm install

Aby sprawdzić, czy korzystasz z właściwego projektu, skonfiguruj go za pomocą tego polecenia gcloud:

gcloud config set project [PROJECT_ID]

Włączanie interfejsów API

Oto interfejsy API, które musimy włączyć w naszym projekcie:

  • Cloud Data Loss Prevention API – udostępnia metody wykrywania, analizy ryzyka i deidentyfikacji poufnych fragmentów w tekście, obrazach i repozytoriach miejsca na dane Google Cloud Platform.
  • Interfejs API usługi Cloud Key Management Service (KMS) – Google Cloud KMS umożliwia klientom zarządzanie kluczami szyfrowania i wykonywanie związanych z nimi operacji kryptograficznych.

Włącz wymagane interfejsy API za pomocą tego polecenia gcloud:

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

3. Sprawdzanie ciągów znaków i plików

Katalog przykładów projektu pobrany w poprzednim kroku zawiera kilka plików JavaScript, które korzystają z różnych funkcji Cloud DLP. inspect.js sprawdzi podany ciąg znaków lub plik pod kątem typów informacji poufnych.

Aby to przetestować, możesz udostępnić opcję string i przykładowy ciąg znaków z pewnymi potencjalnie poufnymi informacjami:

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

Dane wyjściowe powinny zawierać wyniki dla każdego pasującego typu informacji, w tym:

Cytat: Szablon określa

InfoType: typ informacji wykryty w przypadku tej części ciągu znaków. Pełną listę możliwych typów informacji znajdziesz tutaj. Domyślnie inspect.js będzie sprawdzać tylko typy informacji CREDIT_CARD_NUMBER, PHONE_NUMBER i EMAIL_ADDRESS

Prawdopodobieństwo: wyniki są klasyfikowane na podstawie prawdopodobieństwa dopasowania. Prawdopodobieństwo w zakresie od VERY_UNLIKELY do VERY_LIKELY.

Wyniki w przypadku powyższego żądania polecenia to:

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

W podobny sposób możemy sprawdzać pliki pod kątem typów informacji. Sprawdź przykładowy plik accounts.txt:

resources/accounts.txt

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

Uruchom ponownie polecenie inspect.js, tym razem z opcją pliku:

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

Efekty:

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

W przypadku obu rodzajów zapytań możemy ograniczyć wyniki na podstawie prawdopodobieństwa lub typu informacji. Na przykład:

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

Określenie VERY_LIKELY jako prawdopodobieństwa minimalnego spowoduje wykluczenie wszystkich dopasowań mniejszych niż VERY_LIKELY:

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

Pełne wyniki bez żadnych ograniczeń to:

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

Podobnie możemy określić typ informacji, które sprawdzamy:

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

Zwrócony zostanie tylko określony typ informacji:

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

Poniżej znajduje się funkcja asynchroniczna, która do badania danych wejściowych używa interfejsu API:

inspect.js

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

Argumenty podane dla powyższych parametrów są używane do tworzenia obiektu żądania. Żądanie to jest następnie przekazywane do funkcji inspectContent w celu uzyskania odpowiedzi, której wynikiem są nasze dane wyjściowe:

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. Deidentyfikacja

Poza wykrywaniem i badaniem danych wrażliwych Cloud DLP może też przeprowadzać deidentyfikację. Deidentyfikacja to proces usuwania z danych informacji umożliwiających identyfikację. Interfejs API wykrywa dane wrażliwe zdefiniowane za pomocą typów informacji, a potem stosuje przekształcenie deidentyfikujące, aby zamaskować, usunąć lub zasłaniać dane w inny sposób.

deid.js zademonstruje deidentyfikację na kilka sposobów. Najprostszą metodą deidentyfikacji jest użycie maski:

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

Po zastosowaniu maski interfejs API będzie domyślnie zastępować znaki pasującego typu informacji innym znakiem (*). Wynikiem będzie:

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

Zwróć uwagę, że adres e-mail w ciągu jest zaciemniony, mimo że przypadkowy numer zamówienia pozostaje niezmieniony. (Niestandardowe typy informacji są możliwe, ale nie są uwzględnione w tym ćwiczeniu z programowania).

Zobaczmy funkcję, która korzysta z interfejsu DLP API do deidentyfikacji za pomocą maski:

deid.js

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

Również te argumenty służą do tworzenia obiektu żądania. Tym razem jest ona podana do funkcji 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);

Deidentyfikacja za pomocą szyfrowania formatu z zachowaniem szyfrowania

Interfejs DLP API umożliwia również szyfrowanie wartości poufnych danych za pomocą klucza kryptograficznego.

Zaczniemy od utworzenia pęku kluczy Cloud KMS:

gcloud kms keyrings create dlp-keyring --location global

Teraz możemy utworzyć klucz, którego będziemy używać do szyfrowania danych:

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

Interfejs DLP API zaakceptuje opakowany klucz zaszyfrowany utworzonym przez nas kluczem KMS. Możemy wygenerować losowy ciąg, który zostanie zapakowany. Te informacje będą nam później potrzebne do ponownej identyfikacji:

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

Teraz możemy zaszyfrować ciąg znaków naszym kluczem KMS. Wygeneruje to plik binarny zawierający zaszyfrowany ciąg znaków jako tekst szyfrowany:

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

Korzystając z metody deid.js, możemy teraz za pomocą szyfrowania deidentyfikować numer telefonu w przykładowym ciągu poniżej:

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

Dane wyjściowe zwracają ciąg znaków z pasującymi typami informacji, które są zastąpione zaszyfrowanym ciągiem znaków i poprzedzone typem informacji wskazanym przez flagę -s:

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

Przyjrzyjmy się funkcji, której używamy do deidentyfikacji ciągu:

deid.js

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

Te argumenty służą do budowania obiektu cryptoReplaceFfxFpeConfig:

deid.js

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

Obiekt cryptoReplaceFfxFpeConfig jest z kolei używany w żądaniu wysyłanym do interfejsu API za pomocą funkcji 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);

Ponowna identyfikacja danych

Aby ponownie zidentyfikować dane, interfejs DLP API użyje tekstu zaszyfrowanego utworzonego w poprzednim kroku:

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

Wynikiem będzie pierwotny ciąg znaków bez podanych informacji o usuwaniu treści ani typu zastępczego:

My client's cell is 9006492568

Funkcja służąca do ponownej identyfikacji danych jest podobna do funkcji służącej do ich deidentyfikacji:

deid.js

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

I podobnie, argumenty są używane w żądaniu wysyłanym do interfejsu API, tym razem w funkcji 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);

Deidentyfikacja dat za pomocą przesunięcia daty

W niektórych kontekstach daty mogą być uznawane za dane wrażliwe, które możemy zaciemnić. Przesuwanie dat umożliwia przesuwanie dat o losowy przyrost przy zachowaniu kolejności i czasu trwania przedziału czasu. Każda data w zestawie jest przesunięta o określony czas (unikalny dla tego wpisu). Aby zademonstrować deidentyfikację przez przesunięcie daty, spójrz na przykładowy plik CSV zawierający dane daty:

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

Dane zawierają 2 pola, do których możemy zastosować przesunięcie daty: birth_date i register_date. Parametr deid.js akceptuje zarówno dolną, jak i górną wartość granicy, aby zdefiniować zakres, o jaki losowy numer dnia ma być przesuwany:

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

Zostanie wygenerowany plik o nazwie datesShifted.csv z losowymi datami przesuniętymi o liczbę dni z zakresu od 30 do 90. Oto przykład wygenerowanych danych:

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

Zwróć uwagę, że mogliśmy też określić, którą kolumnę daty w pliku CSV chcesz przesunąć. Pole birth_date Pole register_date pozostaje bez zmian.

Przyjrzyjmy się funkcji, która obsługuje deidentyfikację za pomocą przesunięcia daty:

deid.js

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

Zauważ, że ta funkcja może akceptować opakowany klucz i nazwę klucza, podobnie jak w przypadku deidentyfikacji przez FPE. Dzięki temu mamy możliwość udostępnienia klucza szyfrowania w celu ponownej identyfikacji przesunięcia daty. Udostępniane przez nas argumenty tworzą obiekt 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. Usuwanie ciągów znaków i obrazów

Inną metodą maskowania informacji poufnych jest usunięcie. Usuwanie dopasowania spowoduje zastąpienie dopasowania typem informacji, z którym został zidentyfikowany jako pasujący. redact.js obsługuje pomijanie danych:

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

Numer przykładowej karty kredytowej w danych wyjściowych jest zastępowany typem informacji CREDIT_CARD_NUMBER:

Please refund the purchase on my credit card [CREDIT_CARD_NUMBER]

Jest to przydatne, gdy chcesz ukryć informacje poufne, ale jednocześnie określić typ usuwanych informacji. Interfejs DLP API może w podobny sposób usuwać informacje z obrazów zawierających tekst. Aby to sprawdzić, spójrzmy na przykładowy obraz:

resources/test.png

bf3719cfeb5676ff.png

Aby usunąć numer telefonu i adres e-mail z obrazu powyżej:

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

Zgodnie z określonymi danymi zostanie wygenerowany nowy obraz o nazwie redacted.png z zamazanymi informacjami:

ce023dd95cccc40f.png

Oto funkcja służąca do pomijania ciągu znaków:

redact.js

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

A oto żądanie, które zostanie przekazane do funkcji deidentifyContent:

redact.js

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

Podobnie działa funkcja zasłaniania obrazu:

redact.js

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

A oto żądanie, które zostanie przekazane do funkcji 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. Czyszczenie danych

Opracowaliśmy sposoby wykorzystania interfejsu DLP API do maskowania, deidentyfikacji i usuwania informacji poufnych z naszych danych. Czas wyczyścić wszystkie utworzone w projekcie zasoby.

Usuwanie projektu

W konsoli GCP otwórz stronę Cloud Resource Manager (Menedżer zasobów Cloud):

Na liście projektów wybierz ten, nad którym pracujemy, i kliknij Usuń. Pojawi się prośba o wpisanie identyfikatora projektu. Wpisz go i kliknij Wyłącz.

Możesz też usunąć cały projekt bezpośrednio z Cloud Shell przy użyciu gcloud:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

7. Gratulacje!

Super! Udało się! Cloud DLP to zaawansowane narzędzie, które zapewnia dostęp do zaawansowanej platformy do kontroli, klasyfikacji i deidentyfikacji danych wrażliwych.

Omówione zagadnienia

  • Omówiliśmy, jak można wykorzystać Cloud DLP API do badania ciągów znaków i plików pod kątem wielu typów informacji.
  • Dowiedzieliśmy się, jak interfejs DLP API może deidentyfikować ciągi znaków z użyciem maski, aby ukryć typy informacji pasujące do danych
  • Wykorzystaliśmy interfejs DLP API, aby użyć klucza szyfrowania do deidentyfikacji i ponownej identyfikacji danych
  • Zastosowaliśmy interfejs DLP API, aby usunąć dane z ciągu znaków, a także obrazu