Cloud Data Loss Prevention – Übersicht

1. Übersicht

Cloud Data Loss Prevention (DLP) ist ein vollständig verwalteter Dienst zum Auffinden, Klassifizieren und Schützen vertraulicher Informationen. In diesem Codelab werden einige grundlegende Funktionen der Cloud DLP API vorgestellt und verschiedene Möglichkeiten zum Schutz von Daten gezeigt.

Aufgabe

  • DLP verwenden, um Strings und Dateien auf übereinstimmende Infotypen zu prüfen
  • Informationen zu De-Identifikationstechniken und die Verwendung von DLP zur De-Identifikation von Daten
  • Informationen zum Re-Identifizieren von Daten, die mithilfe von formaterhaltender Verschlüsselung (FPE) de-identifiziert wurden
  • DLP verwenden, um infoTypes aus Strings und Bildern zu entfernen

Voraussetzungen

  • Ein Google Cloud-Projekt mit eingerichteter Abrechnung. Falls Sie kein Google Ads-Konto haben, müssen Sie eines erstellen.

2. Einrichtung

Dieses Codelab kann vollständig auf der Google Cloud Platform ausgeführt werden, ohne dass eine lokale Installation oder Konfiguration erforderlich ist.

Cloud Shell

In diesem Codelab stellen wir verschiedene Cloud-Ressourcen und -Dienste über die Cloud Shell-Befehlszeile bereit und verwalten sie.

Laden Sie das Begleitprojekt-Repository herunter:

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

Wechseln Sie nach dem Herunterladen des Projektcodes zum Beispielverzeichnis und installieren Sie die erforderlichen Node.js-Pakete:

cd samples && npm install

Achten Sie darauf, dass Sie das richtige Projekt verwenden, indem Sie es mit dem folgenden gcloud-Befehl festlegen:

gcloud config set project [PROJECT_ID]

APIs aktivieren

Die folgenden APIs müssen für unser Projekt aktiviert werden:

  • Cloud Data Loss Prevention API: bietet Methoden zur Erkennung, Risikoanalyse und De-Identifikation datenschutzsensibler Fragmente in Text, Bildern und Google Cloud Platform-Speicher-Repositories
  • Cloud Key Management Service (KMS) API: Mit Google Cloud KMS können Kunden Verschlüsselungsschlüssel verwalten und kryptografische Vorgänge mit diesen Schlüsseln durchführen.

Aktivieren Sie die erforderlichen APIs mit dem folgenden gcloud-Befehl:

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

3. Strings und Dateien prüfen

Das im vorherigen Schritt heruntergeladene Beispielverzeichnis des Projekts enthält mehrere JavaScript-Dateien, die die verschiedenen Funktionen von Cloud DLP nutzen. inspect.js prüft einen bereitgestellten String oder eine Datei auf Typen von vertraulichen Daten.

Um dies zu testen, können Sie die Option string und einen Beispielstring mit einigen potenziell vertraulichen Informationen bereitstellen:

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

Die Ausgabe sollte die Ergebnisse für jeden übereinstimmenden Infotyp enthalten, darunter:

Zitat: In der Vorlage wird angegeben,

InfoType: Der für diesen Teil des Strings erkannte Informationstyp. Eine vollständige Liste der möglichen infoTypes findest du hier. Standardmäßig prüft inspect.js nur die Infotypen CREDIT_CARD_NUMBER, PHONE_NUMBER UND EMAIL_ADDRESS

Wahrscheinlichkeit: Die Ergebnisse werden danach kategorisiert, wie wahrscheinlich es ist, dass sie eine Übereinstimmung darstellen. Die Wahrscheinlichkeit kann zwischen VERY_UNLIKELY und VERY_LIKELY liegen.

Die Ergebnisse für die obige Befehlsanfrage lauten wie folgt:

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

In ähnlicher Weise können wir Dateien auf Infotypen prüfen. Sehen Sie sich die Beispieldatei accounts.txt an:

resources/accounts.txt

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

Führen Sie inspect.js noch einmal aus, diesmal mit der Dateioption:

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

Das Ergebnis:

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

Bei beiden Arten von Abfragen könnten wir die Ergebnisse nach Wahrscheinlichkeit oder Infotyp beschränken. Beispiel:

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

Wenn Sie VERY_LIKELY als Mindestwahrscheinlichkeit festlegen, werden Übereinstimmungen kleiner als VERY_LIKELY ausgeschlossen:

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

Die vollständigen Ergebnisse ohne die Begrenzung wären:

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

In ähnlicher Weise könnten wir den Infotyp angeben, nach dem geprüft werden soll:

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

Nur der angegebene Infotyp wird zurückgegeben, wenn er gefunden wird:

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

Nachfolgend sehen Sie die asynchrone Funktion, die die Eingabe mithilfe der API überprüft:

inspect.js

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

Die für die oben genannten Parameter angegebenen Argumente werden verwendet, um ein Anfrageobjekt zu erstellen. Diese Anfrage wird dann an die Funktion inspectContent übergeben, um eine Antwort zu erhalten, die zu unserer Ausgabe führt:

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. De-Identifikation

Neben der Prüfung und Erkennung sensibler Daten kann Cloud DLP auch eine De-Identifikation durchführen. Der Prozess, bei dem identifizierende Informationen aus Daten entfernt werden, wird als De-Identifikation bezeichnet. Die API erkennt sensible Daten gemäß der Definition von Infotypen und verwendet dann eine De-Identifikationstransformation, um die Daten zu maskieren, zu löschen oder anderweitig zu verschleiern.

Mit deid.js können Sie die De-Identifikation auf verschiedene Arten demonstrieren. Die einfachste Methode zur De-Identifikation ist eine Maske:

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

Bei einer Maske ersetzt die API die Zeichen des übereinstimmenden Infotyps standardmäßig durch ein anderes Zeichen – *. Die Ausgabe sieht so aus:

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

Beachten Sie, dass die E-Mail-Adresse im String verschleiert ist, während die willkürliche Bestellnummer intakt ist. (Benutzerdefinierte Infotypen sind möglich, werden in diesem Codelab jedoch nicht behandelt.)

Sehen wir uns die Funktion an, die die DLP API zur De-Identifikation mit einer Maske verwendet:

deid.js

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

Diese Argumente werden wiederum zum Erstellen eines Anfrageobjekts verwendet. Dieses Mal wird er der Funktion deidentifyContent zur Verfügung gestellt:

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

Mit formaterhaltender Verschlüsselung de-identifizieren

Die DLP API bietet auch die Möglichkeit, sensible Datenwerte mithilfe eines kryptografischen Schlüssels zu verschlüsseln.

Zuerst erstellen Sie mit Cloud KMS einen Schlüsselbund:

gcloud kms keyrings create dlp-keyring --location global

Jetzt können wir einen Schlüssel zum Verschlüsseln der Daten erstellen:

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

Die DLP API akzeptiert einen verpackten Schlüssel, der mit dem erstellten KMS-Schlüssel verschlüsselt ist. Wir können eine zufällige Zeichenfolge generieren, die umschlossen wird. Wir benötigen sie später, um Folgendes zu re-identifizieren:

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

Jetzt können wir den String mit unserem KMS-Schlüssel verschlüsseln. Dadurch wird eine Binärdatei generiert, die den verschlüsselten String als Geheimtext enthält:

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

Mit deid.js können wir jetzt die Telefonnummer im folgenden Beispielstring durch Verschlüsselung de-identifizieren:

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

Die Ausgabe gibt den String mit den übereinstimmenden infoTypes zurück, die durch einen verschlüsselten String ersetzt und dem durch das Flag -s angegebenen infoType vorangestellt ist:

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

Werfen wir einen Blick auf die Funktion, mit der wir den String de-identifizieren:

deid.js

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

Die Argumente werden zum Erstellen eines cryptoReplaceFfxFpeConfig-Objekts verwendet:

deid.js

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

Das Objekt cryptoReplaceFfxFpeConfig wird wiederum in der Anfrage an die API über die Funktion deidentifyContent verwendet:

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

Daten neu identifizieren

Um die Daten zu re-identifizieren, verwendet die DLP API den Geheimtext, den wir im vorherigen Schritt erstellt haben:

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

Die Ausgabe ist der ursprüngliche String ohne Entfernungen oder den Ersatztyp:

My client's cell is 9006492568

Die zur Re-Identifikation von Daten verwendete Funktion ähnelt der zur De-Identifikation der Daten:

deid.js

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

Auch hier werden die Argumente in einer Anfrage an die API verwendet, diesmal an die Funktion 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);

Datumsangaben mit Datumsverschiebung de-identifizieren

In bestimmten Kontexten können Datumsangaben als sensible Daten betrachtet werden, die wir möglicherweise verschleiern möchten. Bei der Datumsverschiebung können die Datumsangaben um ein zufälliges Inkrement verschoben werden, wobei die Reihenfolge und Dauer eines Zeitraums beibehalten wird. Jedes Datum in einer Gruppe wird um einen bestimmten Zeitraum verschoben, der für diesen Eintrag eindeutig ist. Um die De-Identifikation durch Datumsverschiebung zu veranschaulichen, werfen Sie zuerst einen Blick auf die Beispieldatei im CSV-Format, die Datumsangaben enthält:

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

Die Daten enthalten zwei Felder, auf die wir eine Datumsverschiebung anwenden könnten: birth_date und register_date. deid.js akzeptiert einen unteren und einen oberen Grenzwert, um einen Bereich zu definieren und eine zufällige Anzahl von Tagen auszuwählen, um die die Datumsangaben verschoben werden sollen:

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

Eine Datei mit dem Namen datesShifted.csv wird erstellt, in der die Datumsangaben nach dem Zufallsprinzip um eine Anzahl von Tagen zwischen 30 und 90 verschoben werden. Hier ein Beispiel für die generierte Ausgabe:

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

Beachten Sie, dass Sie auch angeben konnten, welche Datumsspalte in der CSV-Datei verschoben werden soll. Das Feld birth_date Das Feld register_date bleibt unverändert.

Sehen wir uns die Funktion an, die die De-Identifikation mit einer Datumsverschiebung verarbeitet:

deid.js

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

Beachten Sie, dass diese Funktion, ähnlich wie bei der De-Identifikation mit FPE, einen verpackten Schlüssel und einen Schlüsselnamen akzeptieren könnte, sodass wir die Möglichkeit haben, einen Verschlüsselungsschlüssel zur Re-Identifikation einer Datumsverschiebung bereitzustellen. Mit den bereitgestellten Argumenten wird ein dateShiftConfig-Objekt erstellt:

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. Strings und Bilder entfernen

Eine weitere Methode zur Verschleierung vertraulicher Informationen ist das Entfernen. Beim Entfernen wird eine Übereinstimmung durch den infoType ersetzt, mit dem sie abgeglichen werden soll. redact.js zeigt das Entfernen von Daten:

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

In der Ausgabe wird die Beispiel-Kreditkartennummer durch den infoType CREDIT_CARD_NUMBER ersetzt:

Please refund the purchase on my credit card [CREDIT_CARD_NUMBER]

Dies ist nützlich, wenn Sie vertrauliche Informationen ausblenden möchten, aber dennoch die Art der zu entfernenden Informationen angeben möchten. Die DLP API kann auf ähnliche Weise Informationen aus Bildern entfernen, die Text enthalten. Sehen wir uns zur Veranschaulichung ein Beispielbild an:

resources/test.png

bf3719cfeb5676ff.png

So entfernen Sie Telefonnummer und E-Mail-Adresse aus dem Bild oben:

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

Wie angegeben, wird ein neues Bild namens redacted.png erzeugt, wobei die angeforderten Informationen geschwärzt werden:

ce023dd95cccc40f.png

Hier ist die Funktion, die zum Entfernen aus einem String verwendet wird:

redact.js

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

Und hier ist die Anfrage, die an die Funktion deidentifyContent gesendet wird:

redact.js

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

Ähnlich verhält es sich mit der Funktion zum Entfernen von Daten aus einem Bild:

redact.js

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

Und hier ist die Anfrage, die an die Funktion redactImage gesendet wird:

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

Wir haben untersucht, wie wir die DLP API verwenden können, um vertrauliche Informationen aus unseren Daten zu maskieren, zu de-identifizieren und zu entfernen. Jetzt ist es an der Zeit, alle von uns erstellten Ressourcen in unserem Projekt zu bereinigen.

Projekt löschen

Rufen Sie in der GCP Console die Seite Cloud Resource Manager auf:

Wählen Sie in der Projektliste das Projekt aus, an dem Sie gearbeitet haben, und klicken Sie auf Löschen. Sie werden aufgefordert, die Projekt-ID einzugeben. Geben Sie den Code ein und klicken Sie auf Herunterfahren.

Alternativ können Sie das gesamte Projekt mit gcloud direkt aus Cloud Shell löschen:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

7. Glückwunsch!

Hurra! Geschafft! Cloud DLP ist ein leistungsstarkes Tool, das Zugriff auf eine leistungsstarke Plattform für die Prüfung, Klassifizierung und De-Identifikation sensibler Daten bietet.

Behandelte Themen

  • Wir haben gesehen, wie mit der Cloud DLP API Strings und Dateien auf mehrere infoTypes geprüft werden können.
  • Sie haben gelernt, wie die DLP API Strings mit einer Maske de-identifizieren kann, um infoTypes für den Abgleich von Daten auszublenden
  • Wir haben die DLP API verwendet, um einen Verschlüsselungsschlüssel zu verwenden, um Daten zu de-identifizieren und anschließend neu zu identifizieren.
  • Wir haben die DLP API verwendet, um Daten aus einem String und einem Bild zu entfernen.