Sensible Daten de-identifizieren

Cloud Data Loss Prevention (DLP) kann die Identifikation sensibler Daten in Textinhalten aufheben, einschließlich in Containerstrukturen wie Tabellen. Der Prozess des Entfernens von identifizierenden Informationen aus Daten wird als De-Identifikation bezeichnet. Die API erkennt vertrauliche Daten wie personenidentifizierbare Informationen (PII) und verwendet dann eine De-Identifikationstransformation, um die Daten zu maskieren, zu löschen oder anderweitig zu verschleiern. Zu den De-Identifikationstechniken gehören zum Beispiel:

  • "Maskieren" sensibler Daten durch teilweises oder vollständiges Ersetzen von Zeichen durch ein Symbol, etwa ein Sternchen (*) oder Rautezeichen (#)
  • Ersetzen jedes Vorkommens sensibler Daten durch ein "Token" oder einen Ersatzstring
  • Verschlüsseln und Ersetzen von sensiblen Daten mit einem zufällig generierten oder vordefinierten Schlüssel

Wenn Sie Daten mithilfe der infoType-Transformationen CryptoReplaceFfxFpeConfig oder CryptoDeterministicConfig de-identifizieren, können Sie diese Daten wieder identifizieren, sofern Sie den CryptoKey haben, der ursprünglichen bei der De-Identifikation verwendet wurde.

Sie können der API mithilfe von JSON über HTTPS sowie anhand der Befehlszeile und mehrerer Programmiersprachen unter Verwendung der DLP-Clientbibliotheken Informationen zuführen. Informationen zur Verwendung der Befehlszeile finden Sie in der Kurzanleitung. Näheres zum Übergeben von Informationen im JSON-Format finden Sie in der JSON-Kurzanleitung.

API-Übersicht

Verwenden Sie zum De-Identifizieren sensibler Daten die Methode content.deidentify von Cloud DLP.

Ein API-Aufruf zur De-Identifizierung besteht aus drei Teilen:

  • Zu überprüfende Daten: Ein String oder eine Tabellenstruktur (ContentItem-Objekt), der bzw. die von der API überprüft werden soll.
  • Wonach zu suchen ist: Informationen zur Erkennungskonfiguration (InspectConfig), zum Beispiel, welche Datentypen (oder infoTypes) gesucht werden sollen, ob Ergebnisse über einem bestimmten Wahrscheinlichkeitsschwellenwert gefiltert werden sollen, ob nicht mehr als eine bestimmte Anzahl von Ergebnissen geliefert werden soll usw. Wenn nicht mindestens ein infoType in einem InspectConfig-Argument angegeben wird, entspricht dies der Angabe aller integrierten infoTypes. Dies wird nicht empfohlen, da es zu verminderter Leistung und höheren Kosten führen kann.
  • Was mit den Inspektionsergebnissen geschehen soll: Konfigurationsinformationen (DeidentifyConfig), die festlegen, wie die sensiblen Daten de-identifiziert werden sollen. Dieser Aspekt wird im folgenden Abschnitt ausführlicher behandelt.

Die API gibt dieselben Elemente, die Sie angegeben haben, im selben Format zurück. Aber Text, der gemäß Ihren Kriterien als vertrauliche Informationen erkannt wurde, ist jetzt de-identifiziert.

Erkennungskriterien angeben

Informationstyp- bzw. infoType-Detektoren sind die Mechanismen, mit deren Hilfe Cloud DLP nach sensiblen Daten sucht.

Cloud DLP enthält mehrere Arten von infoType-Detektoren, die hier zusammengefasst sind:

  • Integrierte infoType-Detektoren sind in Cloud DLP eingebunden. Dazu gehören Detektoren für länder- oder regionsspezifische sensible Datentypen sowie global anwendbare Datentypen.
  • Benutzerdefinierte infoType-Detektoren sind Detektoren, die Sie selbst erstellen. Es gibt drei Arten von benutzerdefinierten infoType-Detektoren:
    • Reguläre benutzerdefinierte Wörterbuchdetektoren sind einfache Wortlisten, in denen Cloud DLP nach Übereinstimmungen sucht. Verwenden Sie reguläre benutzerdefinierte Wörterbuchdetektoren, wenn Sie eine Liste von einigen Zehntausend Wörtern oder Wortgruppen haben. Reguläre benutzerdefinierte Wörterbuchdetektoren werden bevorzugt verwendet, wenn davon auszugehen ist, dass sich die Wortliste nicht wesentlich ändern wird.
    • Gespeicherte benutzerdefinierte Wörterbuchdetektoren werden von Cloud DLP unter Verwendung umfangreicher Listen von Wörtern oder Wortgruppen generiert, die entweder in Cloud Storage oder BigQuery gespeichert sind. Verwenden Sie gespeicherte benutzerdefinierte Wörterbuchdetektoren, wenn Sie eine umfangreiche Liste von Wörtern oder Wortgruppen haben (bis zu mehreren zehn Millionen).
    • Detektoren regulärer Ausdrücke (Regex-Detektoren) ermöglichen es Cloud DLP, Übereinstimmungen anhand eines regulären Ausdrucksmusters zu erkennen.

Außerdem gilt in Cloud DLP das Konzept der Inspektionsregeln, mit denen Sie die Scanergebnisse auf folgende Weise verfeinern können:

  • Ausschlussregeln können Sie einem integrierten oder benutzerdefinierten infoType-Detektor hinzufügen, um die Anzahl der Ergebnisse einzugrenzen.
  • Hotword-Regeln können Sie einem integrierten oder benutzerdefinierten infoType-Detektor hinzufügen, um die Anzahl der Ergebnisse zu erhöhen oder den Wahrscheinlichkeitswert der Ausgabe zu ändern.

Transformationen zur De-Identifikation

Sie müssen eine oder mehrere Transformationen angeben, wenn Sie die De-Identifikationskonfiguration (DeidentifyConfig) festlegen. Es gibt zwei Transformationskategorien:

  • InfoTypeTransformations: Transformationen, die nur auf Werte innerhalb von gesendetem Text angewendet werden, die als spezifischer infoType gekennzeichnet sind.
  • RecordTransformations: Transformationen, die nur auf Werte innerhalb gesendeter Tabellentextdaten angewendet werden, die als spezifischer infoType gekennzeichnet sind, oder auf eine ganze Spalte von Tabellendaten.

InfoType-Transformationen

Sie können eine oder mehrere infoType-Transformationen pro Anfrage angeben. In jedem InfoTypeTransformation-Objekt geben Sie Folgendes an:

  • Einen oder mehrere infoTypes, auf die eine Transformation angewendet werden soll (das Array-Objekt infoTypes[]).
  • Eine primitive Transformation (das Objekt PrimitiveTransformation).

Die Angabe eines infoTypes ist optional, doch ein InspectConfig-Argument, in dem nicht mindestens ein infoType angegeben ist, bewirkt die Anwendung der Transformation auf alle eingebundenen infoTypes, für die keine Transformation angegeben wurde. Dies wird nicht empfohlen, da es zu verminderter Leistung und höheren Kosten führen kann.

Primitive Transformationen

Sie müssen mindestens eine primitive Transformation angeben, die auf Eingaben angewendet werden soll. Dabei spielt es keine Rolle, ob sie nur auf bestimmte infoTypes oder auf den gesamten Textstring angewendet werden soll. Sie haben mehrere Transformationsoptionen, die in der folgenden Tabelle zusammengefasst sind. Klicken Sie auf den Objektnamen, um weitere Informationen abzurufen.

Die vollständige Liste möglicher Transformationen.

replaceConfig

Wenn Sie replaceConfig für ein ReplaceValueConfig-Objekt festlegen, werden übereinstimmende Eingabewerte durch einen von Ihnen angegebenen Wert ersetzt.

Angenommen, Sie haben replaceConfig für alle infoTypes EMAIL_ADDRESS auf [email-address] festgelegt und der folgende String wird an Cloud DLP gesendet:

My name is Alicia Abernathy, and my email address is aabernathy@example.com.

Der zurückgegebene String sieht so aus:

My name is Alicia Abernathy, and my email address is [email-address].

Das folgende JSON-Beispiel zeigt, wie die API-Anfrage formuliert wird und was die Cloud DLP API zurückgibt:

JSON-Eingabe:

POST https://dlp.googleapis.com/v2/projects/[PROJECT_ID]/content:deidentify?key={YOUR_API_KEY}

{
  "item":{
    "value":"My name is Alicia Abernathy, and my email address is aabernathy@example.com."
  },
  "deidentifyConfig":{
    "infoTypeTransformations":{
      "transformations":[
        {
          "infoTypes":[
            {
              "name":"EMAIL_ADDRESS"
            }
          ],
          "primitiveTransformation":{
            "replaceConfig":{
              "newValue":{
                "stringValue":"[email-address]"
              }
            }
          }
        }
      ]
    }
  },
  "inspectConfig":{
    "infoTypes":[
      {
        "name":"EMAIL_ADDRESS"
      }
    ]
  }
}

JSON-Ausgabe:

{
  "item":{
    "value":"My name is Alicia Abernathy, and my email address is [email-address]."
  },
  "overview":{
    "transformedBytes":"22",
    "transformationSummaries":[
      {
        "infoType":{
          "name":"EMAIL_ADDRESS"
        },
        "transformation":{
          "replaceConfig":{
            "newValue":{
              "stringValue":"[email-address]"
            }
          }
        },
        "results":[
          {
            "count":"1",
            "code":"SUCCESS"
          }
        ],
        "transformedBytes":"22"
      }
    ]
  }
}
redactConfig

Wenn Sie redactConfig angeben, wird ein bestimmter Wert vollständig entfernt. Die redactConfig-Meldung hat keine Argumente. Allein dadurch, dass sie angegeben wird, wird ihre Transformation aktiviert.

Angenommen, Sie haben redactConfig für alle infoTypes EMAIL_ADDRESS angegeben und es wird der folgende String an Cloud DLP gesendet:

My name is Alicia Abernathy, and my email address is aabernathy@example.com.

Der zurückgegebene String sieht so aus:

My name is Alicia Abernathy, and my email address is .

Das folgende JSON-Beispiel zeigt, wie die API-Anfrage formuliert wird und was die Cloud DLP API zurückgibt:

JSON-Eingabe:

POST https://dlp.googleapis.com/v2/projects/[PROJECT_ID]/content:deidentify?key={YOUR_API_KEY}

{
  "item":{
    "value":"My name is Alicia Abernathy, and my email address is aabernathy@example.com."
  },
  "deidentifyConfig":{
    "infoTypeTransformations":{
      "transformations":[
        {
          "infoTypes":[
            {
              "name":"EMAIL_ADDRESS"
            }
          ],
          "primitiveTransformation":{
            "redactConfig":{

            }
          }
        }
      ]
    }
  },
  "inspectConfig":{
    "infoTypes":[
      {
        "name":"EMAIL_ADDRESS"
      }
    ]
  }
}

JSON-Ausgabe:

{
  "item":{
    "value":"My name is Alicia Abernathy, and my email address is ."
  },
  "overview":{
    "transformedBytes":"22",
    "transformationSummaries":[
      {
        "infoType":{
          "name":"EMAIL_ADDRESS"
        },
        "transformation":{
          "redactConfig":{

          }
        },
        "results":[
          {
            "count":"1",
            "code":"SUCCESS"
          }
        ],
        "transformedBytes":"22"
      }
    ]
  }
}
characterMaskConfig

Wenn Sie characterMaskConfig für ein CharacterMaskConfig-Objekt festlegen, wird ein String teilweise maskiert, wobei eine bestimmte Anzahl von Zeichen durch ein festgelegtes Zeichen ersetzt wird. Die Maskierung kann vom Anfang oder Ende des Strings aus beginnen. Diese Transformation funktioniert auch mit Zahlentypen wie etwa langen Ganzzahlen.

Das Objekt CharacterMaskConfig hat mehrere eigene Argumente:

  • maskingCharacter: Das Zeichen, das zum Maskieren jedes Zeichens eines sensiblen Werts verwendet wird. Sie können beispielsweise ein Sternchen (*) oder eine Raute (#) angeben, um eine Reihe von Zahlen zu verbergen, zum Beispiel die Zahlen einer Kreditkartennummer.
  • numberToMask: Anzahl der Zeichen, die maskiert werden sollen. Wenn Sie diesen Wert nicht festlegen, werden alle übereinstimmenden Zeichen maskiert.
  • reverseOrder: Die Angabe, ob Zeichen in umgekehrter Reihenfolge maskiert werden sollen. Wenn reverseOrder mit "true" festgelegt wird, werden Zeichen in übereinstimmenden Werten vom Ende bis zum Anfang des Werts maskiert. Wenn "false" festgelegt wird, beginnt die Maskierung am Anfang des Werts.
  • charactersToIgnore[]: Ein oder mehrere Zeichen, die beim Maskieren von Werten übersprungen werden sollen. Geben Sie hier beispielsweise einen Bindestrich an, um die Bindestriche bei der Maskierung einer Telefonnummer beizubehalten. Sie können auch eine Gruppe allgemeiner Zeichen (CharsToIgnore) angeben, die beim Maskieren ignoriert werden sollen.

Das folgende JSON-Beispiel zeigt, wie die API-Anfrage formuliert wird und was die Cloud DLP API zurückgibt:

JSON-Eingabe:

POST https://dlp.googleapis.com/v2/projects/[PROJECT_ID]/content:deidentify?key={YOUR_API_KEY}

{
  "item":{
    "value":"My name is Alicia Abernathy, and my email address is aabernathy@example.com."
  },
  "deidentifyConfig":{
    "infoTypeTransformations":{
      "transformations":[
        {
          "infoTypes":[
            {
              "name":"EMAIL_ADDRESS"
            }
          ],
          "primitiveTransformation":{
            "characterMaskConfig":{
              "maskingCharacter":"#",
              "reverseOrder":false,
              "charactersToIgnore":[
                {
                  "charactersToSkip":".@"
                }
              ]
            }
          }
        }
      ]
    }
  },
  "inspectConfig":{
    "infoTypes":[
      {
        "name":"EMAIL_ADDRESS"
      }
    ]
  }
}

JSON-Ausgabe:

{
  "item":{
    "value":"My name is Alicia Abernathy, and my email address is ##########@#######.###."
  },
  "overview":{
    "transformedBytes":"22",
    "transformationSummaries":[
      {
        "infoType":{
          "name":"EMAIL_ADDRESS"
        },
        "transformation":{
          "characterMaskConfig":{
            "maskingCharacter":"#",
            "charactersToIgnore":[
              {
                "charactersToSkip":".@"
              }
            ]
          }
        },
        "results":[
          {
            "count":"1",
            "code":"SUCCESS"
          }
        ],
        "transformedBytes":"22"
      }
    ]
  }
}

Dieses Beispiel veranschaulicht, was mit dem folgenden String geschieht, wenn er an Cloud DLP gesendet wird und characterMaskConfig festgelegt ist:

My name is Alicia Abernathy, and my email address is aabernathy@example.com.

Cloud DLP gibt Folgendes zurück:

My name is Alicia Abernathy, and my email address is ##########@#######.###.

Der folgende Beispielcode in mehreren Sprachen zeigt, wie mithilfe der Cloud DLP API sensible Daten durch Maskierungsverfahren de-identifiziert werden.

Java


import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.privacy.dlp.v2.CharacterMaskConfig;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.DeidentifyConfig;
import com.google.privacy.dlp.v2.DeidentifyContentRequest;
import com.google.privacy.dlp.v2.DeidentifyContentResponse;
import com.google.privacy.dlp.v2.InfoType;
import com.google.privacy.dlp.v2.InfoTypeTransformations;
import com.google.privacy.dlp.v2.InfoTypeTransformations.InfoTypeTransformation;
import com.google.privacy.dlp.v2.InspectConfig;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.ProjectName;
import com.google.privacy.dlp.v2.ReplaceWithInfoTypeConfig;
import java.io.IOException;
import java.util.Arrays;

public class DeIdentifyWithMasking {

  public static void deIdentifyWithMasking() throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String textToDeIdentify = "My SSN is 372819127";
    deIdentifyWithMasking(projectId, textToDeIdentify);
  }

  public static void deIdentifyWithMasking(String projectId, String textToDeIdentify)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (DlpServiceClient dlp = DlpServiceClient.create()) {

      // Specify what content you want the service to DeIdentify
      ContentItem contentItem = ContentItem.newBuilder().setValue(textToDeIdentify).build();

      // Specify the type of info the inspection will look for.
      // See https://cloud.google.com/dlp/docs/infotypes-reference for complete list of info types
      InfoType infoType = InfoType.newBuilder().setName("US_SOCIAL_SECURITY_NUMBER").build();
      InspectConfig inspectConfig =
          InspectConfig.newBuilder().addAllInfoTypes(Arrays.asList(infoType)).build();

      // Specify how the info from the inspection should be masked.
      CharacterMaskConfig characterMaskConfig =
          CharacterMaskConfig.newBuilder()
              .setMaskingCharacter("X") // Character to replace the found info with
              .setNumberToMask(5) // How many characters should be masked
              .build();
      PrimitiveTransformation primitiveTransformation =
          PrimitiveTransformation.newBuilder()
              .setReplaceWithInfoTypeConfig(ReplaceWithInfoTypeConfig.getDefaultInstance())
              .build();
      InfoTypeTransformation infoTypeTransformation =
          InfoTypeTransformation.newBuilder()
              .setPrimitiveTransformation(primitiveTransformation)
              .build();
      InfoTypeTransformations transformations =
          InfoTypeTransformations.newBuilder().addTransformations(infoTypeTransformation).build();

      DeidentifyConfig deidentifyConfig =
          DeidentifyConfig.newBuilder().setInfoTypeTransformations(transformations).build();

      // Combine configurations into a request for the service.
      DeidentifyContentRequest request =
          DeidentifyContentRequest.newBuilder()
              .setParent(ProjectName.of(projectId).toString())
              .setItem(contentItem)
              .setInspectConfig(inspectConfig)
              .setDeidentifyConfig(deidentifyConfig)
              .build();

      // Send the request and receive response from the service
      DeidentifyContentResponse response = dlp.deidentifyContent(request);

      // Print the results
      System.out.println("Text after masking: " + response.getItem().getValue());
    }
  }
}

Node.js

// Imports the Google Cloud Data Loss Prevention library
const DLP = require('@google-cloud/dlp');

// Instantiates a client
const dlp = new DLP.DlpServiceClient();

// The project ID to run the API call under
// const callingProjectId = process.env.GCLOUD_PROJECT;

// The string to deidentify
// const string = 'My SSN is 372819127';

// (Optional) The maximum number of sensitive characters to mask in a match
// If omitted from the request or set to 0, the API will mask any matching characters
// const numberToMask = 5;

// (Optional) The character to mask matching sensitive data with
// const maskingCharacter = 'x';

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

try {
  // Run deidentification request
  const [response] = await dlp.deidentifyContent(request);
  const deidentifiedItem = response.item;
  console.log(deidentifiedItem.value);
} catch (err) {
  console.log(`Error in deidentifyWithMask: ${err.message || err}`);
}

Python

def deidentify_with_mask(
    project, string, info_types, masking_character=None, number_to_mask=0
):
    """Uses the Data Loss Prevention API to deidentify sensitive data in a
    string by masking it with a character.
    Args:
        project: The Google Cloud project id to use as a parent resource.
        item: The string to deidentify (will be treated as text).
        masking_character: The character to mask matching sensitive data with.
        number_to_mask: The maximum number of sensitive characters to mask in
            a match. If omitted or set to zero, the API will default to no
            maximum.
    Returns:
        None; the response from the API is printed to the terminal.
    """

    # Import the client library
    import google.cloud.dlp

    # Instantiate a client
    dlp = google.cloud.dlp_v2.DlpServiceClient()

    # Convert the project id into a full resource id.
    parent = dlp.project_path(project)

    # Construct inspect configuration dictionary
    inspect_config = {
        "info_types": [{"name": info_type} for info_type in info_types]
    }

    # Construct deidentify configuration dictionary
    deidentify_config = {
        "info_type_transformations": {
            "transformations": [
                {
                    "primitive_transformation": {
                        "character_mask_config": {
                            "masking_character": masking_character,
                            "number_to_mask": number_to_mask,
                        }
                    }
                }
            ]
        }
    }

    # Construct item
    item = {"value": string}

    # Call the API
    response = dlp.deidentify_content(
        parent,
        inspect_config=inspect_config,
        deidentify_config=deidentify_config,
        item=item,
    )

    # Print out the results.
    print(response.item.value)

Go

import (
	"context"
	"fmt"
	"io"

	dlp "cloud.google.com/go/dlp/apiv2"
	dlppb "google.golang.org/genproto/googleapis/privacy/dlp/v2"
)

// mask deidentifies the input by masking all provided info types with maskingCharacter
// and prints the result to w.
func mask(w io.Writer, projectID, input string, infoTypeNames []string, maskingCharacter string, numberToMask int32) error {
	// projectID := "my-project-id"
	// input := "My SSN is 111222333"
	// infoTypeNames := []string{"US_SOCIAL_SECURITY_NUMBER"}
	// maskingCharacter := "+"
	// numberToMask := 6
	// Will print "My SSN is ++++++333"

	ctx := context.Background()
	client, err := dlp.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("dlp.NewClient: %v", err)
	}
	// Convert the info type strings to a list of InfoTypes.
	var infoTypes []*dlppb.InfoType
	for _, it := range infoTypeNames {
		infoTypes = append(infoTypes, &dlppb.InfoType{Name: it})
	}
	// Create a configured request.
	req := &dlppb.DeidentifyContentRequest{
		Parent: "projects/" + projectID,
		InspectConfig: &dlppb.InspectConfig{
			InfoTypes: infoTypes,
		},
		DeidentifyConfig: &dlppb.DeidentifyConfig{
			Transformation: &dlppb.DeidentifyConfig_InfoTypeTransformations{
				InfoTypeTransformations: &dlppb.InfoTypeTransformations{
					Transformations: []*dlppb.InfoTypeTransformations_InfoTypeTransformation{
						{
							InfoTypes: []*dlppb.InfoType{}, // Match all info types.
							PrimitiveTransformation: &dlppb.PrimitiveTransformation{
								Transformation: &dlppb.PrimitiveTransformation_CharacterMaskConfig{
									CharacterMaskConfig: &dlppb.CharacterMaskConfig{
										MaskingCharacter: maskingCharacter,
										NumberToMask:     numberToMask,
									},
								},
							},
						},
					},
				},
			},
		},
		// The item to analyze.
		Item: &dlppb.ContentItem{
			DataItem: &dlppb.ContentItem_Value{
				Value: input,
			},
		},
	}
	// Send the request.
	r, err := client.DeidentifyContent(ctx, req)
	if err != nil {
		return fmt.Errorf("DeidentifyContent: %v", err)
	}
	// Print the result.
	fmt.Fprint(w, r.GetItem().GetValue())
	return nil
}

PHP

/**
 * Deidentify sensitive data in a string by masking it with a character.
 */
use Google\Cloud\Dlp\V2\CharacterMaskConfig;
use Google\Cloud\Dlp\V2\DlpServiceClient;
use Google\Cloud\Dlp\V2\InfoType;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\InfoTypeTransformations\InfoTypeTransformation;
use Google\Cloud\Dlp\V2\InfoTypeTransformations;
use Google\Cloud\Dlp\V2\ContentItem;

/** Uncomment and populate these variables in your code */
// $callingProjectId = 'The GCP Project ID to run the API call under';
// $string = 'The string to deidentify';
// $numberToMask = 0; // (Optional) The maximum number of sensitive characters to mask in a match
// $maskingCharacter = 'x'; // (Optional) The character to mask matching sensitive data with

// Instantiate a client.
$dlp = new DlpServiceClient();

// The infoTypes of information to mask
$ssnInfoType = (new InfoType())
    ->setName('US_SOCIAL_SECURITY_NUMBER');
$infoTypes = [$ssnInfoType];

// Create the masking configuration object
$maskConfig = (new CharacterMaskConfig())
    ->setMaskingCharacter($maskingCharacter)
    ->setNumberToMask($numberToMask);

// Create the information transform configuration objects
$primitiveTransformation = (new PrimitiveTransformation())
    ->setCharacterMaskConfig($maskConfig);

$infoTypeTransformation = (new InfoTypeTransformation())
    ->setPrimitiveTransformation($primitiveTransformation)
    ->setInfoTypes($infoTypes);

$infoTypeTransformations = (new InfoTypeTransformations())
    ->setTransformations([$infoTypeTransformation]);

// Create the deidentification configuration object
$deidentifyConfig = (new DeidentifyConfig())
    ->setInfoTypeTransformations($infoTypeTransformations);

$item = (new ContentItem())
    ->setValue($string);

$parent = $dlp->projectName($callingProjectId);

// Run request
$response = $dlp->deidentifyContent($parent, [
    'deidentifyConfig' => $deidentifyConfig,
    'item' => $item
]);

// Print the results
$deidentifiedValue = $response->getItem()->getValue();
print($deidentifiedValue);

C#

public static object DeidMask(
    string projectId,
    string dataValue,
    IEnumerable<InfoType> infoTypes,
    string maskingCharacter,
    int numberToMask,
    bool reverseOrder)
{
    var request = new DeidentifyContentRequest
    {
        ParentAsProjectName = new ProjectName(projectId),
        InspectConfig = new InspectConfig
        {
            InfoTypes = { infoTypes }
        },
        DeidentifyConfig = new DeidentifyConfig
        {
            InfoTypeTransformations = new InfoTypeTransformations
            {
                Transformations = {
                    new InfoTypeTransformations.Types.InfoTypeTransformation
                    {
                        PrimitiveTransformation = new PrimitiveTransformation
                        {
                            CharacterMaskConfig = new CharacterMaskConfig
                            {
                                MaskingCharacter = maskingCharacter,
                                NumberToMask = numberToMask,
                                ReverseOrder = reverseOrder
                            }
                        }
                    }
                }
            }
        },
        Item = new ContentItem
        {
            Value = dataValue
        }
    };

    DlpServiceClient dlp = DlpServiceClient.Create();
    var response = dlp.DeidentifyContent(request);

    Console.WriteLine($"Deidentified content: {response.Item.Value}");
    return 0;
}

cryptoHashConfig

Wenn Sie cryptoHashConfig für ein CryptoHashConfig-Objekt festlegen, wird eine Pseudonymisierung für einen Eingabewert ausgeführt, wobei ein Ersatzwert durch kryptografisches Hashing erzeugt wird.

Diese Methode ersetzt den Eingabewert durch einen verschlüsselten "Digest"- oder Hash-Wert. Zur Berechnung des Digest wird der SHA-256-Hash des Eingabewerts verwendet. Der kryptografische Schlüssel zum Erstellen des Hash-Werts ist ein CryptoKey-Objekt und muss entweder 32 oder 64 Byte groß sein.

Die Methode gibt eine base64-codierte Darstellung der Hash-Ausgabe aus. Derzeit können nur Stringwerte und ganzzahlige Werte gehasht werden.

Angenommen, Sie haben cryptoHashConfig für alle infoTypes EMAIL_ADDRESS angegeben und das CryptoKey-Objekt besteht aus einem zufällig generierten Schlüssel (einem TransientCryptoKey), dann wird der folgende String an Cloud DLP gesendet:

My name is Alicia Abernathy, and my email address is aabernathy@example.com.

Der kryptografisch erzeugte zurückgegebene String sieht folgendermaßen aus:

My name is Alicia Abernathy, and my email address is 41D1567F7F99F1DC2A5FAB886DEE5BEE.

Natürlich wird der hexadezimale String kryptografisch erzeugt und unterscheidet sich von dem hier gezeigten.

dateShiftConfig

Wenn Sie dateShiftConfig für ein DateShiftConfig-Objekt festlegen, erfolgt eine Datumsverschiebung eines Datumseingabewerts durch Verschieben der Angaben um eine zufällige Anzahl von Tagen.

Verfahren zur Datumsverschiebung verlagern eine Reihe von Datumsangaben um einen zufälligen Wert, behalten aber die Reihenfolge und Dauer bei. Die Datumsverschiebung wird in der Regel in Bezug auf Einzelpersonen oder Entitäten verwendet. Das heißt, Sie verschieben alle Daten einer bestimmten Person um denselben Verschiebungsfaktor, aber mit anderen Verschiebungsfaktoren für andere Personen.

Weitere Informationen zum Verschieben von Datumsangaben finden Sie unter Datumsverschiebung.

Der folgende Beispielcode in mehreren Sprachen zeigt, wie mithilfe der Cloud DLP API Daten durch Datumsverschiebung de-identifiziert werden.

Java


import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.common.base.Splitter;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.DateShiftConfig;
import com.google.privacy.dlp.v2.DeidentifyConfig;
import com.google.privacy.dlp.v2.DeidentifyContentRequest;
import com.google.privacy.dlp.v2.DeidentifyContentResponse;
import com.google.privacy.dlp.v2.FieldId;
import com.google.privacy.dlp.v2.FieldTransformation;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.ProjectName;
import com.google.privacy.dlp.v2.RecordTransformations;
import com.google.privacy.dlp.v2.Table;
import com.google.privacy.dlp.v2.Value;
import com.google.type.Date;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class DeIdentifyWithDateShift {

  public static void deIdentifyWithDateShift() throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    Path inputCsvFile = Paths.get("path/to/your/input/file.csv");
    Path outputCsvFile = Paths.get("path/to/your/output/file.csv");
    deIdentifyWithDateShift(projectId, inputCsvFile, outputCsvFile);
  }

  public static void deIdentifyWithDateShift(
      String projectId, Path inputCsvFile, Path outputCsvFile) throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (DlpServiceClient dlp = DlpServiceClient.create()) {
      // Read the contents of the CSV file into a Table
      List<FieldId> headers;
      List<Table.Row> rows;
      try (BufferedReader input = Files.newBufferedReader(inputCsvFile)) {
        // Parse and convert the first line into header names
        headers =
            Arrays.stream(input.readLine().split(","))
                .map(header -> FieldId.newBuilder().setName(header).build())
                .collect(Collectors.toList());
        // Parse the remainder of the file as Table.Rows
        rows =
            input.lines().map(DeIdentifyWithDateShift::parseLineAsRow).collect(Collectors.toList());
      }
      Table table = Table.newBuilder().addAllHeaders(headers).addAllRows(rows).build();
      ContentItem item = ContentItem.newBuilder().setTable(table).build();

      // Set the maximum days to shift dates backwards (lower bound) or forward (upper bound)
      DateShiftConfig dateShiftConfig =
          DateShiftConfig.newBuilder().setLowerBoundDays(5).setUpperBoundDays(5).build();
      PrimitiveTransformation transformation =
          PrimitiveTransformation.newBuilder().setDateShiftConfig(dateShiftConfig).build();
      // Specify which fields the DateShift should apply too
      List<FieldId> dateFields = Arrays.asList(headers.get(1), headers.get(3));
      FieldTransformation fieldTransformation =
          FieldTransformation.newBuilder()
              .addAllFields(dateFields)
              .setPrimitiveTransformation(transformation)
              .build();
      RecordTransformations recordTransformations =
          RecordTransformations.newBuilder().addFieldTransformations(fieldTransformation).build();
      // Specify the config for the de-identify request
      DeidentifyConfig deidentifyConfig =
          DeidentifyConfig.newBuilder().setRecordTransformations(recordTransformations).build();

      // Combine configurations into a request for the service.
      DeidentifyContentRequest request =
          DeidentifyContentRequest.newBuilder()
              .setParent(ProjectName.of(projectId).toString())
              .setItem(item)
              .setDeidentifyConfig(deidentifyConfig)
              .build();

      // Send the request and receive response from the service
      DeidentifyContentResponse response = dlp.deidentifyContent(request);

      // Write the results to the target CSV file
      try (BufferedWriter writer = Files.newBufferedWriter(outputCsvFile)) {
        Table outTable = response.getItem().getTable();
        String headerOut =
            outTable.getHeadersList().stream()
                .map(FieldId::getName)
                .collect(Collectors.joining(","));
        writer.write(headerOut + "\n");

        List<String> rowOutput =
            outTable.getRowsList().stream()
                .map(row -> joinRow(row.getValuesList()))
                .collect(Collectors.toList());
        for (String line : rowOutput) {
          writer.write(line + "\n");
        }
        System.out.println("Content written to file: " + outputCsvFile.toString());
      }
    }
  }

  // Convert the string from the csv file into com.google.type.Date
  public static Date parseAsDate(String s) {
    LocalDate date = LocalDate.parse(s, DateTimeFormatter.ofPattern("MM/dd/yyyy"));
    return Date.newBuilder()
        .setDay(date.getDayOfMonth())
        .setMonth(date.getMonthValue())
        .setYear(date.getYear())
        .build();
  }

  // Each row is in the format: Name,BirthDate,CreditCardNumber,RegisterDate
  public static Table.Row parseLineAsRow(String line) {
    List<String> values = Splitter.on(",").splitToList(line);
    Value name = Value.newBuilder().setStringValue(values.get(0)).build();
    Value birthDate = Value.newBuilder().setDateValue(parseAsDate(values.get(1))).build();
    Value creditCardNumber = Value.newBuilder().setStringValue(values.get(2)).build();
    Value registerDate = Value.newBuilder().setDateValue(parseAsDate(values.get(3))).build();
    return Table.Row.newBuilder()
        .addValues(name)
        .addValues(birthDate)
        .addValues(creditCardNumber)
        .addValues(registerDate)
        .build();
  }

  public static String formatDate(Date d) {
    return String.format("%s/%s/%s", d.getMonth(), d.getDay(), d.getYear());
  }

  public static String joinRow(List<Value> values) {
    String name = values.get(0).getStringValue();
    String birthDate = formatDate(values.get(1).getDateValue());
    String creditCardNumber = values.get(2).getStringValue();
    String registerDate = formatDate(values.get(3).getDateValue());
    return String.join(",", name, birthDate, creditCardNumber, registerDate);
  }
}

Node.js

// Imports the Google Cloud Data Loss Prevention library
const DLP = require('@google-cloud/dlp');

// Instantiates a client
const dlp = new DLP.DlpServiceClient();

// Import other required libraries
const fs = require('fs');

// The project ID to run the API call under
// const callingProjectId = process.env.GCLOUD_PROJECT;

// The path to the CSV file to deidentify
// The first row of the file must specify column names, and all other rows
// must contain valid values
// const inputCsvFile = '/path/to/input/file.csv';

// The path to save the date-shifted CSV file to
// const outputCsvFile = '/path/to/output/file.csv';

// The list of (date) fields in the CSV file to date shift
// const dateFields = [{ name: 'birth_date'}, { name: 'register_date' }];

// The maximum number of days to shift a date backward
// const lowerBoundDays = 1;

// The maximum number of days to shift a date forward
// const upperBoundDays = 1;

// (Optional) The column to determine date shift amount based on
// If this is not specified, a random shift amount will be used for every row
// If this is specified, then 'wrappedKey' and 'keyName' must also be set
// const contextFieldId = [{ name: 'user_id' }];

// (Optional) The name of the Cloud KMS key used to encrypt ('wrap') the AES-256 key
// If this is specified, then 'wrappedKey' and 'contextFieldId' must also be set
// const keyName = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME';

// (Optional) The encrypted ('wrapped') AES-256 key to use when shifting dates
// This key should be encrypted using the Cloud KMS key specified above
// If this is specified, then 'keyName' and 'contextFieldId' must also be set
// const wrappedKey = 'YOUR_ENCRYPTED_AES_256_KEY'

// Helper function for converting CSV rows to Protobuf types
const rowToProto = row => {
  const values = row.split(',');
  const convertedValues = values.map(value => {
    if (Date.parse(value)) {
      const date = new Date(value);
      return {
        dateValue: {
          year: date.getFullYear(),
          month: date.getMonth() + 1,
          day: date.getDate(),
        },
      };
    } else {
      // Convert all non-date values to strings
      return {stringValue: value.toString()};
    }
  });
  return {values: convertedValues};
};

// Read and parse a CSV file
const csvLines = fs
  .readFileSync(inputCsvFile)
  .toString()
  .split('\n')
  .filter(line => line.includes(','));
const csvHeaders = csvLines[0].split(',');
const csvRows = csvLines.slice(1);

// Construct the table object
const tableItem = {
  table: {
    headers: csvHeaders.map(header => {
      return {name: header};
    }),
    rows: csvRows.map(row => rowToProto(row)),
  },
};

// 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,
};

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

  // Write results to a CSV file
  tableRows.forEach((row, rowIndex) => {
    const rowValues = row.values.map(
      value =>
        value.stringValue ||
        `${value.dateValue.month}/${value.dateValue.day}/${value.dateValue.year}`
    );
    csvLines[rowIndex + 1] = rowValues.join(',');
  });
  csvLines.push('');
  fs.writeFileSync(outputCsvFile, csvLines.join('\n'));

  // Print status
  console.log(`Successfully saved date-shift output to ${outputCsvFile}`);
} catch (err) {
  console.log(`Error in deidentifyWithDateShift: ${err.message || err}`);
}

Python

def deidentify_with_date_shift(
    project,
    input_csv_file=None,
    output_csv_file=None,
    date_fields=None,
    lower_bound_days=None,
    upper_bound_days=None,
    context_field_id=None,
    wrapped_key=None,
    key_name=None,
):
    """Uses the Data Loss Prevention API to deidentify dates in a CSV file by
        pseudorandomly shifting them.
    Args:
        project: The Google Cloud project id to use as a parent resource.
        input_csv_file: The path to the CSV file to deidentify. The first row
            of the file must specify column names, and all other rows must
            contain valid values.
        output_csv_file: The path to save the date-shifted CSV file.
        date_fields: The list of (date) fields in the CSV file to date shift.
            Example: ['birth_date', 'register_date']
        lower_bound_days: The maximum number of days to shift a date backward
        upper_bound_days: The maximum number of days to shift a date forward
        context_field_id: (Optional) The column to determine date shift amount
            based on. If this is not specified, a random shift amount will be
            used for every row. If this is specified, then 'wrappedKey' and
            'keyName' must also be set. Example:
            contextFieldId = [{ 'name': 'user_id' }]
        key_name: (Optional) The name of the Cloud KMS key used to encrypt
            ('wrap') the AES-256 key. Example:
            key_name = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/
            keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME'
        wrapped_key: (Optional) The encrypted ('wrapped') AES-256 key to use.
            This key should be encrypted using the Cloud KMS key specified by
            key_name.
    Returns:
        None; the response from the API is printed to the terminal.
    """
    # Import the client library
    import google.cloud.dlp

    # Instantiate a client
    dlp = google.cloud.dlp_v2.DlpServiceClient()

    # Convert the project id into a full resource id.
    parent = dlp.project_path(project)

    # Convert date field list to Protobuf type
    def map_fields(field):
        return {"name": field}

    if date_fields:
        date_fields = map(map_fields, date_fields)
    else:
        date_fields = []

    # Read and parse the CSV file
    import csv
    from datetime import datetime

    f = []
    with open(input_csv_file, "r") as csvfile:
        reader = csv.reader(csvfile)
        for row in reader:
            f.append(row)

    #  Helper function for converting CSV rows to Protobuf types
    def map_headers(header):
        return {"name": header}

    def map_data(value):
        try:
            date = datetime.strptime(value, "%m/%d/%Y")
            return {
                "date_value": {
                    "year": date.year,
                    "month": date.month,
                    "day": date.day,
                }
            }
        except ValueError:
            return {"string_value": value}

    def map_rows(row):
        return {"values": map(map_data, row)}

    # Using the helper functions, convert CSV rows to protobuf-compatible
    # dictionaries.
    csv_headers = map(map_headers, f[0])
    csv_rows = map(map_rows, f[1:])

    # Construct the table dict
    table_item = {"table": {"headers": csv_headers, "rows": csv_rows}}
    # Construct date shift config
    date_shift_config = {
        "lower_bound_days": lower_bound_days,
        "upper_bound_days": upper_bound_days,
    }

    # If using a Cloud KMS key, add it to the date_shift_config.
    # The wrapped key is base64-encoded, but the library expects a binary
    # string, so decode it here.
    if context_field_id and key_name and wrapped_key:
        import base64

        date_shift_config["context"] = {"name": context_field_id}
        date_shift_config["crypto_key"] = {
            "kms_wrapped": {
                "wrapped_key": base64.b64decode(wrapped_key),
                "crypto_key_name": key_name,
            }
        }
    elif context_field_id or key_name or wrapped_key:
        raise ValueError(
            """You must set either ALL or NONE of
        [context_field_id, key_name, wrapped_key]!"""
        )

    # Construct Deidentify Config
    deidentify_config = {
        "record_transformations": {
            "field_transformations": [
                {
                    "fields": date_fields,
                    "primitive_transformation": {
                        "date_shift_config": date_shift_config
                    },
                }
            ]
        }
    }

    # Write to CSV helper methods
    def write_header(header):
        return header.name

    def write_data(data):
        return data.string_value or "%s/%s/%s" % (
            data.date_value.month,
            data.date_value.day,
            data.date_value.year,
        )

    # Call the API
    response = dlp.deidentify_content(
        parent, deidentify_config=deidentify_config, item=table_item
    )

    # Write results to CSV file
    with open(output_csv_file, "w") as csvfile:
        write_file = csv.writer(csvfile, delimiter=",")
        write_file.writerow(map(write_header, response.item.table.headers))
        for row in response.item.table.rows:
            write_file.writerow(map(write_data, row.values))
    # Print status
    print("Successfully saved date-shift output to {}".format(output_csv_file))

Go

import (
	"context"
	"fmt"
	"io"

	dlp "cloud.google.com/go/dlp/apiv2"
	dlppb "google.golang.org/genproto/googleapis/privacy/dlp/v2"
)

// deidentifyDateShift shifts dates found in the input between lowerBoundDays and
// upperBoundDays.
func deidentifyDateShift(w io.Writer, projectID string, lowerBoundDays, upperBoundDays int32, input string) error {
	// projectID := "my-project-id"
	// lowerBoundDays := -1
	// upperBound := -1
	// input := "2016-01-10"
	// Will print "2016-01-09"
	ctx := context.Background()
	client, err := dlp.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("dlp.NewClient: %v", err)
	}
	// Create a configured request.
	req := &dlppb.DeidentifyContentRequest{
		Parent: "projects/" + projectID,
		DeidentifyConfig: &dlppb.DeidentifyConfig{
			Transformation: &dlppb.DeidentifyConfig_InfoTypeTransformations{
				InfoTypeTransformations: &dlppb.InfoTypeTransformations{
					Transformations: []*dlppb.InfoTypeTransformations_InfoTypeTransformation{
						{
							InfoTypes: []*dlppb.InfoType{}, // Match all info types.
							PrimitiveTransformation: &dlppb.PrimitiveTransformation{
								Transformation: &dlppb.PrimitiveTransformation_DateShiftConfig{
									DateShiftConfig: &dlppb.DateShiftConfig{
										LowerBoundDays: lowerBoundDays,
										UpperBoundDays: upperBoundDays,
									},
								},
							},
						},
					},
				},
			},
		},
		// The InspectConfig is used to identify the DATE fields.
		InspectConfig: &dlppb.InspectConfig{
			InfoTypes: []*dlppb.InfoType{
				{
					Name: "DATE",
				},
			},
		},
		// The item to analyze.
		Item: &dlppb.ContentItem{
			DataItem: &dlppb.ContentItem_Value{
				Value: input,
			},
		},
	}
	// Send the request.
	r, err := client.DeidentifyContent(ctx, req)
	if err != nil {
		return fmt.Errorf("DeidentifyContent: %v", err)
	}
	// Print the result.
	fmt.Fprint(w, r.GetItem().GetValue())
	return nil
}

PHP

/**
 * Deidentify dates in a CSV file by pseudorandomly shifting them.
 */
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\CryptoKey;
use Google\Cloud\Dlp\V2\DateShiftConfig;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\DlpServiceClient;
use Google\Cloud\Dlp\V2\FieldId;
use Google\Cloud\Dlp\V2\FieldTransformation;
use Google\Cloud\Dlp\V2\KmsWrappedCryptoKey;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;
use Google\Cloud\Dlp\V2\RecordTransformations;
use Google\Cloud\Dlp\V2\Table;
use Google\Cloud\Dlp\V2\Table\Row;
use Google\Cloud\Dlp\V2\Value;
use Google\Type\Date;

/** Uncomment and populate these variables in your code */
// $callingProject = 'The GCP Project ID to run the API call under';
// $inputCsvFile = 'The path to the CSV file to deidentify';
// $outputCsvFile = 'The path to save the date-shifted CSV file to';
// $dateFieldNames = 'The comma-separated list of (date) fields in the CSV file to date shift';
// $lowerBoundDays = 'The maximum number of days to shift a date backward';
// $upperBoundDays = 'The maximum number of days to shift a date forward';
/**
 * If contextFieldName is not specified, a random shift amount will be used for every row.
 * If contextFieldName is specified, then 'wrappedKey' and 'keyName' must also be set
 */
// $contextFieldName = ''; (Optional) The column to determine date shift amount based on
// $keyName = ''; // Optional) The encrypted ('wrapped') AES-256 key to use when shifting dates
// $wrappedKey = ''; // (Optional) The name of the Cloud KMS key used to encrypt (wrap) the AES-256 key

// Instantiate a client.
$dlp = new DlpServiceClient();

// Read a CSV file
$csvLines = file($inputCsvFile, FILE_IGNORE_NEW_LINES);
$csvHeaders = explode(',', $csvLines[0]);
$csvRows = array_slice($csvLines, 1);

// Convert CSV file into protobuf objects
$tableHeaders = array_map(function ($csvHeader) {
    return (new FieldId)->setName($csvHeader);
}, $csvHeaders);

$tableRows = array_map(function ($csvRow) {
    $rowValues = array_map(function ($csvValue) {
        if ($csvDate = DateTime::createFromFormat('m/d/Y', $csvValue)) {
            $date = (new Date())
                ->setYear((int) $csvDate->format('Y'))
                ->setMonth((int) $csvDate->format('m'))
                ->setDay((int) $csvDate->format('d'));
            return (new Value())
                ->setDateValue($date);
        } else {
            return (new Value())
                ->setStringValue($csvValue);
        }
    }, explode(',', $csvRow));

    return (new Row())
        ->setValues($rowValues);
}, $csvRows);

// Convert date fields into protobuf objects
$dateFields = array_map(function ($dateFieldName) {
    return (new FieldId())->setName($dateFieldName);
}, explode(',', $dateFieldNames));

// Construct the table object
$table = (new Table())
    ->setHeaders($tableHeaders)
    ->setRows($tableRows);

$item = (new ContentItem())
    ->setTable($table);

// Construct dateShiftConfig
$dateShiftConfig = (new DateShiftConfig())
    ->setLowerBoundDays($lowerBoundDays)
    ->setUpperBoundDays($upperBoundDays);

if ($contextFieldName && $keyName && $wrappedKey) {
    $contextField = (new FieldId())
        ->setName($contextFieldName);

    // Create the wrapped crypto key configuration object
    $kmsWrappedCryptoKey = (new KmsWrappedCryptoKey())
        ->setWrappedKey(base64_decode($wrappedKey))
        ->setCryptoKeyName($keyName);

    $cryptoKey = (new CryptoKey())
        ->setKmsWrapped($kmsWrappedCryptoKey);

    $dateShiftConfig
        ->setContext($contextField)
        ->setCryptoKey($cryptoKey);
} elseif ($contextFieldName || $keyName || $wrappedKey) {
    throw new Exception('You must set either ALL or NONE of {$contextFieldName, $keyName, $wrappedKey}!');
}

// Create the information transform configuration objects
$primitiveTransformation = (new PrimitiveTransformation())
    ->setDateShiftConfig($dateShiftConfig);

$fieldTransformation = (new FieldTransformation())
    ->setPrimitiveTransformation($primitiveTransformation)
    ->setFields($dateFields);

$recordTransformations = (new RecordTransformations())
    ->setFieldTransformations([$fieldTransformation]);

// Create the deidentification configuration object
$deidentifyConfig = (new DeidentifyConfig())
    ->setRecordTransformations($recordTransformations);

$parent = $dlp->projectName($callingProjectId);

// Run request
$response = $dlp->deidentifyContent($parent, [
    'deidentifyConfig' => $deidentifyConfig,
    'item' => $item
]);

// Check for errors
foreach ($response->getOverview()->getTransformationSummaries() as $summary) {
    foreach ($summary->getResults() as $result) {
        if ($details = $result->getDetails()) {
            printf('Error: %s' . PHP_EOL, $details);
            return;
        }
    }
}

// Save the results to a file
$csvRef = fopen($outputCsvFile, 'w');
fputcsv($csvRef, $csvHeaders);
foreach ($response->getItem()->getTable()->getRows() as $tableRow) {
    $values = array_map(function ($tableValue) {
        if ($tableValue->getStringValue()) {
            return $tableValue->getStringValue();
        }
        $protoDate = $tableValue->getDateValue();
        $date = mktime(0, 0, 0, $protoDate->getMonth(), $protoDate->getDay(), $protoDate->getYear());
        return strftime('%D', $date);
    }, iterator_to_array($tableRow->getValues()));
    fputcsv($csvRef, $values);
};
fclose($csvRef);
printf('Deidentified dates written to %s' . PHP_EOL, $outputCsvFile);

C#

public static object DeidDateShift(
    string projectId,
    string inputCsvFile,
    string outputCsvFile,
    int lowerBoundDays,
    int upperBoundDays,
    string dateFields,
    string contextField = "",
    string keyName = "",
    string wrappedKey = "")
{
    var dlp = DlpServiceClient.Create();

    // Read file
    string[] csvLines = File.ReadAllLines(inputCsvFile);
    string[] csvHeaders = csvLines[0].Split(',');
    string[] csvRows = csvLines.Skip(1).ToArray();

    // Convert dates to protobuf format, and everything else to a string
    var protoHeaders = csvHeaders.Select(header => new FieldId { Name = header });
    var protoRows = csvRows.Select(CsvRow =>
    {
        var rowValues = CsvRow.Split(',');
        var protoValues = rowValues.Select(RowValue =>
        {
            System.DateTime parsedDate;
            if (System.DateTime.TryParse(RowValue, out parsedDate))
            {
                return new Value
                {
                    DateValue = new Google.Type.Date
                    {
                        Year = parsedDate.Year,
                        Month = parsedDate.Month,
                        Day = parsedDate.Day
                    }
                };
            }
            else
            {
                return new Value
                {
                    StringValue = RowValue
                };
            }
        });

        var rowObject = new Table.Types.Row();
        rowObject.Values.Add(protoValues);
        return rowObject;
    });

    var dateFieldList = dateFields
        .Split(',')
        .Select(field => new FieldId { Name = field });

    // Construct + execute the request
    var dateShiftConfig = new DateShiftConfig
    {
        LowerBoundDays = lowerBoundDays,
        UpperBoundDays = upperBoundDays
    };
    bool hasKeyName = !String.IsNullOrEmpty(keyName);
    bool hasWrappedKey = !String.IsNullOrEmpty(wrappedKey);
    bool hasContext = !String.IsNullOrEmpty(contextField);
    if (hasKeyName && hasWrappedKey && hasContext)
    {
        dateShiftConfig.Context = new FieldId { Name = contextField };
        dateShiftConfig.CryptoKey = new CryptoKey
        {
            KmsWrapped = new KmsWrappedCryptoKey
            {
                WrappedKey = ByteString.FromBase64(wrappedKey),
                CryptoKeyName = keyName
            }
        };
    }
    else if (hasKeyName || hasWrappedKey || hasContext)
    {
        throw new ArgumentException("Must specify ALL or NONE of: {contextFieldId, keyName, wrappedKey}!");
    }

    var deidConfig = new DeidentifyConfig
    {
        RecordTransformations = new RecordTransformations
        {
            FieldTransformations =
            {
                new FieldTransformation
                {
                    PrimitiveTransformation = new PrimitiveTransformation
                    {
                        DateShiftConfig = dateShiftConfig
                    },
                    Fields = { dateFieldList }
                }
            }
        }
    };

    DeidentifyContentResponse response = dlp.DeidentifyContent(
        new DeidentifyContentRequest
        {
            Parent = $"projects/{projectId}",
            DeidentifyConfig = deidConfig,
            Item = new ContentItem
            {
                Table = new Table
                {
                    Headers = { protoHeaders },
                    Rows = { protoRows }
                }
            }
        });

    // Save the results
    List<String> outputLines = new List<string>();
    outputLines.Add(csvLines[0]);

    outputLines.AddRange(response.Item.Table.Rows.Select(ProtoRow =>
    {
        var Values = ProtoRow.Values.Select(ProtoValue =>
        {
            if (ProtoValue.DateValue != null)
            {
                var ProtoDate = ProtoValue.DateValue;
                System.DateTime Date = new System.DateTime(
                    ProtoDate.Year, ProtoDate.Month, ProtoDate.Day);
                return Date.ToShortDateString();
            }
            else
            {
                return ProtoValue.StringValue;
            }
        });
        return String.Join(',', Values);
    }));

    File.WriteAllLines(outputCsvFile, outputLines);

    return 0;
}

cryptoReplaceFfxFpeConfig

Wenn Sie cryptoReplaceFfxFpeConfig für ein CryptoReplaceFfxFpeConfig-Objekt festlegen, wird eine Pseudonymisierung für einen Eingabewert ausgeführt, wobei ein Eingabewert durch ein Token ersetzt wird. Dieses Token ist:

  • der verschlüsselte Eingabewert
  • gleich lang wie der Eingabewert
  • mithilfe von format-bewahrender Verschlüsselung (FPE) im FFX-Modus, verschlüsselt mit dem von cryptoKey angegebenen kryptografischen Schlüssel berechnet worden
  • aus den mit alphabet angegebenen Zeichen gebildet Gültige Optionen:
    • NUMERIC
    • HEXADECIMAL
    • UPPER_CASE_ALPHA_NUMERIC
    • ALPHA_NUMERIC

Der Eingabewert:

  • muss mindestens zwei Zeichen lang sein (oder der leere String).
  • muss aus den mit alphabet angegebenen Zeichen bestehen und alphabet muss auf 2 bis 64 Zeichen begrenzt sein.

Cloud DLP berechnet das einzusetzende Token mithilfe eines kryptografischen Schlüssels. Zum Angeben dieses Schlüssels haben Sie drei Möglichkeiten:

  1. Unverschlüsselte Einbettung in die API-Anfrage
  2. Anfordern der Generierung des Schlüssels durch Cloud DLP
  3. Verschlüsselte Einbettung in die API-Anfrage – bei dieser Option wird der Schlüssel von einem Cloud KMS-Schlüssel (Cloud Key Management Service) gepackt bzw. verschlüsselt

Zum Erstellen eines gepackten Cloud KMS-Schlüssels senden Sie eine Anfrage mit einem 16-, 24- oder 32-Byte-plaintext-Feldwert an die Cloud KMS-Methode projects.locations.keyRings.cryptoKeys.encrypt. Der gepackte Schlüssel ist der Wert im Feld ciphertext der Antwort der Methode.

Der Wert ist standardmäßig ein base64-codierter String. Zum Festlegen dieses Werts in Cloud DLP muss er in einen Byte-String decodiert werden. Die folgenden Code-Snippets verdeutlichen diesen Vorgang in verschiedenen Sprachen. Im Anschluss an diese Snippets folgen End-to-End-Beispiele.

Java

KmsWrappedCryptoKey.newBuilder()
    .setWrappedKey(ByteString.copyFrom(BaseEncoding.base64().decode(wrappedKey)))

Python

# The wrapped key is Base64-encoded, but the library expects a binary
# string, so decode it here.
import base64
wrapped_key = base64.b64decode(wrapped_key)

PHP

// Create the wrapped crypto key configuration object
$kmsWrappedCryptoKey = (new KmsWrappedCryptoKey())
    ->setWrappedKey(base64_decode($wrappedKey))
    ->setCryptoKeyName($keyName);

C#

WrappedKey = ByteString.FromBase64(wrappedKey)

Weitere Informationen zum Verschlüsseln und Entschlüsseln von Daten mit Cloud KMS finden Sie unter Daten verschlüsseln und entschlüsseln.

Der folgende Beispielcode in mehreren Sprachen zeigt, wie mithilfe von Cloud DLP sensible Daten de-identifiziert werden, indem ein Eingabewert durch ein Token ersetzt wird.

Java


import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.common.io.BaseEncoding;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.CryptoKey;
import com.google.privacy.dlp.v2.CryptoReplaceFfxFpeConfig;
import com.google.privacy.dlp.v2.CryptoReplaceFfxFpeConfig.FfxCommonNativeAlphabet;
import com.google.privacy.dlp.v2.DeidentifyConfig;
import com.google.privacy.dlp.v2.DeidentifyContentRequest;
import com.google.privacy.dlp.v2.DeidentifyContentResponse;
import com.google.privacy.dlp.v2.InfoType;
import com.google.privacy.dlp.v2.InfoTypeTransformations;
import com.google.privacy.dlp.v2.InfoTypeTransformations.InfoTypeTransformation;
import com.google.privacy.dlp.v2.InspectConfig;
import com.google.privacy.dlp.v2.KmsWrappedCryptoKey;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.ProjectName;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.util.Arrays;

public class DeIdentifyWithFpe {

  public static void deIdentifyWithFpe() throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String textToDeIdentify = "I'm Gary and my email is gary@example.com";
    String kmsKeyName =
        "projects/YOUR_PROJECT/"
            + "locations/YOUR_KEYRING_REGION/"
            + "keyRings/YOUR_KEYRING_NAME/"
            + "cryptoKeys/YOUR_KEY_NAME";
    String wrappedAesKey = "YOUR_ENCRYPTED_AES_256_KEY";
    deIdentifyWithFpe(projectId, textToDeIdentify, kmsKeyName, wrappedAesKey);
  }

  public static void deIdentifyWithFpe(
      String projectId, String textToDeIdentify, String kmsKeyName, String wrappedAesKey)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (DlpServiceClient dlp = DlpServiceClient.create()) {
      // Specify what content you want the service to DeIdentify
      ContentItem contentItem = ContentItem.newBuilder().setValue(textToDeIdentify).build();

      // Specify the type of info the inspection will look for.
      // See https://cloud.google.com/dlp/docs/infotypes-reference for complete list of info types
      InfoType infoType = InfoType.newBuilder().setName("US_SOCIAL_SECURITY_NUMBER").build();
      InspectConfig inspectConfig =
          InspectConfig.newBuilder().addAllInfoTypes(Arrays.asList(infoType)).build();

      // Specify an encrypted AES-256 key and the name of the Cloud KMS key that encrypted it
      KmsWrappedCryptoKey kmsWrappedCryptoKey =
          KmsWrappedCryptoKey.newBuilder()
              .setWrappedKey(ByteString.copyFrom(BaseEncoding.base64().decode(wrappedAesKey)))
              .setCryptoKeyName(kmsKeyName)
              .build();
      CryptoKey cryptoKey = CryptoKey.newBuilder().setKmsWrapped(kmsWrappedCryptoKey).build();

      // Specify how the info from the inspection should be encrypted.
      InfoType surrogateInfoType = InfoType.newBuilder().setName("SSN_TOKEN").build();
      CryptoReplaceFfxFpeConfig cryptoReplaceFfxFpeConfig =
          CryptoReplaceFfxFpeConfig.newBuilder()
              .setCryptoKey(cryptoKey)
              // Set of characters in the input text. For more info, see
              // https://cloud.google.com/dlp/docs/reference/rest/v2/organizations.deidentifyTemplates#DeidentifyTemplate.FfxCommonNativeAlphabet
              .setCommonAlphabet(FfxCommonNativeAlphabet.NUMERIC)
              .setSurrogateInfoType(surrogateInfoType)
              .build();
      PrimitiveTransformation primitiveTransformation =
          PrimitiveTransformation.newBuilder()
              .setCryptoReplaceFfxFpeConfig(cryptoReplaceFfxFpeConfig)
              .build();
      InfoTypeTransformation infoTypeTransformation =
          InfoTypeTransformation.newBuilder()
              .setPrimitiveTransformation(primitiveTransformation)
              .build();
      InfoTypeTransformations transformations =
          InfoTypeTransformations.newBuilder().addTransformations(infoTypeTransformation).build();

      DeidentifyConfig deidentifyConfig =
          DeidentifyConfig.newBuilder().setInfoTypeTransformations(transformations).build();

      // Combine configurations into a request for the service.
      DeidentifyContentRequest request =
          DeidentifyContentRequest.newBuilder()
              .setParent(ProjectName.of(projectId).toString())
              .setItem(contentItem)
              .setInspectConfig(inspectConfig)
              .setDeidentifyConfig(deidentifyConfig)
              .build();

      // Send the request and receive response from the service
      DeidentifyContentResponse response = dlp.deidentifyContent(request);

      // Print the results
      System.out.println(
          "Text after format-preserving encryption: " + response.getItem().getValue());
    }
  }
}

Node.js

// Imports the Google Cloud Data Loss Prevention library
const DLP = require('@google-cloud/dlp');

// Instantiates a client
const dlp = new DLP.DlpServiceClient();

// The project ID to run the API call under
// const callingProjectId = process.env.GCLOUD_PROJECT;

// The string to deidentify
// const string = 'My SSN is 372819127';

// The set of characters to replace sensitive ones with
// For more information, see https://cloud.google.com/dlp/docs/reference/rest/v2/organizations.deidentifyTemplates#ffxcommonnativealphabet
// const alphabet = 'ALPHA_NUMERIC';

// The name of the Cloud KMS key used to encrypt ('wrap') the AES-256 key
// const keyName = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME';

// The encrypted ('wrapped') AES-256 key to use
// This key should be encrypted using the Cloud KMS key specified above
// const wrappedKey = 'YOUR_ENCRYPTED_AES_256_KEY'

// (Optional) The name of the surrogate custom info type to use
// Only necessary if you want to reverse the deidentification process
// Can be essentially any arbitrary string, as long as it doesn't appear
// in your dataset otherwise.
// const surrogateType = 'SOME_INFO_TYPE_DEID';

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

// 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);
  const deidentifiedItem = response.item;
  console.log(deidentifiedItem.value);
} catch (err) {
  console.log(`Error in deidentifyWithFpe: ${err.message || err}`);
}

Python

def deidentify_with_fpe(
    project,
    string,
    info_types,
    alphabet=None,
    surrogate_type=None,
    key_name=None,
    wrapped_key=None,
):
    """Uses the Data Loss Prevention API to deidentify sensitive data in a
    string using Format Preserving Encryption (FPE).
    Args:
        project: The Google Cloud project id to use as a parent resource.
        item: The string to deidentify (will be treated as text).
        alphabet: The set of characters to replace sensitive ones with. For
            more information, see https://cloud.google.com/dlp/docs/reference/
            rest/v2beta2/organizations.deidentifyTemplates#ffxcommonnativealphabet
        surrogate_type: The name of the surrogate custom info type to use. Only
            necessary if you want to reverse the deidentification process. Can
            be essentially any arbitrary string, as long as it doesn't appear
            in your dataset otherwise.
        key_name: The name of the Cloud KMS key used to encrypt ('wrap') the
            AES-256 key. Example:
            key_name = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/
            keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME'
        wrapped_key: The encrypted ('wrapped') AES-256 key to use. This key
            should be encrypted using the Cloud KMS key specified by key_name.
    Returns:
        None; the response from the API is printed to the terminal.
    """
    # Import the client library
    import google.cloud.dlp

    # Instantiate a client
    dlp = google.cloud.dlp_v2.DlpServiceClient()

    # Convert the project id into a full resource id.
    parent = dlp.project_path(project)

    # The wrapped key is base64-encoded, but the library expects a binary
    # string, so decode it here.
    import base64

    wrapped_key = base64.b64decode(wrapped_key)

    # Construct FPE configuration dictionary
    crypto_replace_ffx_fpe_config = {
        "crypto_key": {
            "kms_wrapped": {
                "wrapped_key": wrapped_key,
                "crypto_key_name": key_name,
            }
        },
        "common_alphabet": alphabet,
    }

    # Add surrogate type
    if surrogate_type:
        crypto_replace_ffx_fpe_config["surrogate_info_type"] = {
            "name": surrogate_type
        }

    # Construct inspect configuration dictionary
    inspect_config = {
        "info_types": [{"name": info_type} for info_type in info_types]
    }

    # Construct deidentify configuration dictionary
    deidentify_config = {
        "info_type_transformations": {
            "transformations": [
                {
                    "primitive_transformation": {
                        "crypto_replace_ffx_fpe_config": crypto_replace_ffx_fpe_config
                    }
                }
            ]
        }
    }

    # Convert string to item
    item = {"value": string}

    # Call the API
    response = dlp.deidentify_content(
        parent,
        inspect_config=inspect_config,
        deidentify_config=deidentify_config,
        item=item,
    )

    # Print results
    print(response.item.value)

Go

import (
	"context"
	"fmt"
	"io"
	"io/ioutil"

	dlp "cloud.google.com/go/dlp/apiv2"
	dlppb "google.golang.org/genproto/googleapis/privacy/dlp/v2"
)

// deidentifyFPE deidentifies the input with FPE (Format Preserving Encryption).
// keyFileName is the file name with the KMS wrapped key and cryptoKeyName is the
// full KMS key resource name used to wrap the key. surrogateInfoType is an
// optional identifier needed for reidentification. surrogateInfoType can be any
// value not found in your input.
// Info types can be found with the infoTypes.list method or on https://cloud.google.com/dlp/docs/infotypes-reference
func deidentifyFPE(w io.Writer, projectID, input string, infoTypeNames []string, keyFileName, cryptoKeyName, surrogateInfoType string) error {
	// projectID := "my-project-id"
	// input := "My SSN is 123456789"
	// infoTypeNames := []string{"US_SOCIAL_SECURITY_NUMBER"}
	// keyFileName := "projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME"
	// cryptoKeyName := "YOUR_ENCRYPTED_AES_256_KEY"
	// surrogateInfoType := "AGE"
	ctx := context.Background()
	client, err := dlp.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("dlp.NewClient: %v", err)
	}
	// Convert the info type strings to a list of InfoTypes.
	var infoTypes []*dlppb.InfoType
	for _, it := range infoTypeNames {
		infoTypes = append(infoTypes, &dlppb.InfoType{Name: it})
	}
	// Read the key file.
	keyBytes, err := ioutil.ReadFile(keyFileName)
	if err != nil {
		return fmt.Errorf("ReadFile: %v", err)
	}
	// Create a configured request.
	req := &dlppb.DeidentifyContentRequest{
		Parent: "projects/" + projectID,
		InspectConfig: &dlppb.InspectConfig{
			InfoTypes: infoTypes,
		},
		DeidentifyConfig: &dlppb.DeidentifyConfig{
			Transformation: &dlppb.DeidentifyConfig_InfoTypeTransformations{
				InfoTypeTransformations: &dlppb.InfoTypeTransformations{
					Transformations: []*dlppb.InfoTypeTransformations_InfoTypeTransformation{
						{
							InfoTypes: []*dlppb.InfoType{}, // Match all info types.
							PrimitiveTransformation: &dlppb.PrimitiveTransformation{
								Transformation: &dlppb.PrimitiveTransformation_CryptoReplaceFfxFpeConfig{
									CryptoReplaceFfxFpeConfig: &dlppb.CryptoReplaceFfxFpeConfig{
										CryptoKey: &dlppb.CryptoKey{
											Source: &dlppb.CryptoKey_KmsWrapped{
												KmsWrapped: &dlppb.KmsWrappedCryptoKey{
													WrappedKey:    keyBytes,
													CryptoKeyName: cryptoKeyName,
												},
											},
										},
										// Set the alphabet used for the output.
										Alphabet: &dlppb.CryptoReplaceFfxFpeConfig_CommonAlphabet{
											CommonAlphabet: dlppb.CryptoReplaceFfxFpeConfig_ALPHA_NUMERIC,
										},
										// Set the surrogate info type, used for reidentification.
										SurrogateInfoType: &dlppb.InfoType{
											Name: surrogateInfoType,
										},
									},
								},
							},
						},
					},
				},
			},
		},
		// The item to analyze.
		Item: &dlppb.ContentItem{
			DataItem: &dlppb.ContentItem_Value{
				Value: input,
			},
		},
	}
	// Send the request.
	r, err := client.DeidentifyContent(ctx, req)
	if err != nil {
		return fmt.Errorf("DeidentifyContent: %v", err)
	}
	// Print the result.
	fmt.Fprint(w, r.GetItem().GetValue())
	return nil
}

PHP

/**
 * Deidentify a string using Format-Preserving Encryption (FPE).
 */
use Google\Cloud\Dlp\V2\CryptoReplaceFfxFpeConfig;
use Google\Cloud\Dlp\V2\CryptoReplaceFfxFpeConfig\FfxCommonNativeAlphabet;
use Google\Cloud\Dlp\V2\CryptoKey;
use Google\Cloud\Dlp\V2\DlpServiceClient;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;
use Google\Cloud\Dlp\V2\KmsWrappedCryptoKey;
use Google\Cloud\Dlp\V2\InfoType;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\InfoTypeTransformations\InfoTypeTransformation;
use Google\Cloud\Dlp\V2\InfoTypeTransformations;
use Google\Cloud\Dlp\V2\ContentItem;

/** Uncomment and populate these variables in your code */
// $callingProjectId = 'The GCP Project ID to run the API call under';
// $string = 'The string to deidentify';
// $keyName = 'The name of the Cloud KMS key used to encrypt (wrap) the AES-256 key';
// $wrappedKey = 'The name of the Cloud KMS key use, encrypted with the KMS key in $keyName';
// $surrogateTypeName = ''; // (Optional) surrogate custom info type to enable reidentification

// Instantiate a client.
$dlp = new DlpServiceClient();

// The infoTypes of information to mask
$ssnInfoType = (new InfoType())
    ->setName('US_SOCIAL_SECURITY_NUMBER');
$infoTypes = [$ssnInfoType];

// Create the wrapped crypto key configuration object
$kmsWrappedCryptoKey = (new KmsWrappedCryptoKey())
    ->setWrappedKey(base64_decode($wrappedKey))
    ->setCryptoKeyName($keyName);

// The set of characters to replace sensitive ones with
// For more information, see https://cloud.google.com/dlp/docs/reference/rest/V2/organizations.deidentifyTemplates#ffxcommonnativealphabet
$commonAlphabet = FfxCommonNativeAlphabet::NUMERIC;

// Create the crypto key configuration object
$cryptoKey = (new CryptoKey())
    ->setKmsWrapped($kmsWrappedCryptoKey);

// Create the crypto FFX FPE configuration object
$cryptoReplaceFfxFpeConfig = (new CryptoReplaceFfxFpeConfig())
    ->setCryptoKey($cryptoKey)
    ->setCommonAlphabet($commonAlphabet);

if ($surrogateTypeName) {
    $surrogateType = (new InfoType())
        ->setName($surrogateTypeName);
    $cryptoReplaceFfxFpeConfig->setSurrogateInfoType($surrogateType);
}

// Create the information transform configuration objects
$primitiveTransformation = (new PrimitiveTransformation())
    ->setCryptoReplaceFfxFpeConfig($cryptoReplaceFfxFpeConfig);

$infoTypeTransformation = (new InfoTypeTransformation())
    ->setPrimitiveTransformation($primitiveTransformation)
    ->setInfoTypes($infoTypes);

$infoTypeTransformations = (new InfoTypeTransformations())
    ->setTransformations([$infoTypeTransformation]);

// Create the deidentification configuration object
$deidentifyConfig = (new DeidentifyConfig())
    ->setInfoTypeTransformations($infoTypeTransformations);

$content = (new ContentItem())
    ->setValue($string);

$parent = $dlp->projectName($callingProjectId);

// Run request
$response = $dlp->deidentifyContent($parent, [
    'deidentifyConfig' => $deidentifyConfig,
    'item' => $content
]);

// Print the results
$deidentifiedValue = $response->getItem()->getValue();
print($deidentifiedValue);

C#

public static object DeidFpe(
    string projectId,
    string dataValue,
    IEnumerable<InfoType> infoTypes,
    string keyName,
    string wrappedKey,
    string alphabet)
{
    var deidentifyConfig = new DeidentifyConfig
    {
        InfoTypeTransformations = new InfoTypeTransformations
        {
            Transformations =
            {
                new InfoTypeTransformations.Types.InfoTypeTransformation
                {
                    PrimitiveTransformation = new PrimitiveTransformation
                    {
                        CryptoReplaceFfxFpeConfig = new CryptoReplaceFfxFpeConfig
                        {
                            CommonAlphabet = (FfxCommonNativeAlphabet) Enum.Parse(typeof(FfxCommonNativeAlphabet), alphabet),
                            CryptoKey = new CryptoKey
                            {
                                KmsWrapped = new KmsWrappedCryptoKey
                                {
                                    CryptoKeyName = keyName,
                                    WrappedKey = ByteString.FromBase64(wrappedKey)
                                }
                            },
                            SurrogateInfoType = new InfoType
                            {
                                Name = "TOKEN"
                            }
                        }
                    }
                }
            }
        }
    };

    DlpServiceClient dlp = DlpServiceClient.Create();
    var response = dlp.DeidentifyContent(
        new DeidentifyContentRequest
        {
            ParentAsProjectName = new ProjectName(projectId),
            InspectConfig = new InspectConfig
            {
                InfoTypes = { infoTypes }
            },
            DeidentifyConfig = deidentifyConfig,
            Item = new ContentItem { Value = dataValue }
        });

    Console.WriteLine($"Deidentified content: {response.Item.Value}");
    return 0;
}

fixedSizeBucketingConfig

Die Bucketing-Transformationen (diese und bucketingConfig) dienen dazu, numerische Daten durch "Bucketing" in Bereiche zu maskieren. Der sich daraus ergebende Zahlenbereich ist ein String mit Bindestrich, bestehend aus einer unteren Grenze, einem Bindestrich und einer oberen Grenze.

Wenn Sie fixedSizeBucketingConfig für ein FixedSizeBucketingConfig-Objekt festlegen, werden Eingabewerte anhand fester Größenbereiche in Buckets gruppiert. Das FixedSizeBucketingConfig-Objekt besteht aus Folgendem:

  • lowerBound: Der untere Grenzwert aller Buckets. Werte, die unter diesem Wert liegen, werden in einem einzelnen Bucket zusammengefasst.
  • upperBound: Der obere Grenzwert aller Buckets. Größere Werte werden in einem einzigen Bucket zusammengefasst.
  • bucketSize: Die Größe jedes Buckets mit Ausnahme der Buckets, die die Minimal- und Maximalwerte enthalten.

Wenn beispielsweise lowerBound auf 10 gesetzt ist, upperBound auf 89 und bucketSize auf 10, werden die folgenden Buckets verwendet: –10, 10–20, 20–30, 30–40, 40–50, 50–60, 60–70, 70–80, 80–89, 89+.

Weitere Informationen zum Konzept des Bucketings finden Sie unter Generalisierung und Bucketing.

bucketingConfig

Die Transformation bucketingConfig bietet mehr Flexibilität als die andere Bucketing-Transformation fixedSizeBucketingConfig. Anstatt Ober- und Untergrenzen sowie einen Intervallwert anzugeben, um gleich große Buckets zu erstellen, geben Sie die Maximal- und Minimalwerte für jeden Bucket an, den Sie erstellen möchten. Der Typ muss bei allen Paaren aus Maximal- und Minimalwert derselbe sein.

Wenn Sie bucketingConfig für ein BucketingConfig-Objekt festlegen, werden benutzerdefinierte Buckets angegeben. Das BucketingConfig-Objekt besteht aus einem buckets[]-Array mit Bucket-Objekten. Jedes Bucket-Objekt besteht aus Folgendem:

  • min: Untergrenze des Bucket-Bereichs. Lassen Sie diesen Wert aus, um einen Bucket zu erstellen, der keine Untergrenze hat.
  • max: Obergrenze des Bucket-Bereichs. Lassen Sie diesen Wert aus, um einen Bucket zu erstellen, der keine Obergrenze hat.
  • replacementValue: Wert, durch den Werte ersetzt werden sollen, die zwischen die untere und obere Grenze fallen. Wenn Sie keinen replacementValue angeben, wird stattdessen ein min-max-Bereich mit Bindestrich verwendet.

Wenn ein Wert außerhalb der definierten Bereiche liegt, enthält die gelieferte TransformationSummary eine Fehlermeldung.

Betrachten Sie beispielsweise die folgende Konfiguration für die bucketingConfig-Transformation:

"bucketingConfig":{
  "buckets":[
    {
      "min":{
        "integerValue":"1"
      },
      "max":{
        "integerValue":"30"
      },
      "replacementValue":{
        "stringValue":"LOW"
      }
    },
    {
      "min":{
        "integerValue":"31"
      },
      "max":{
        "integerValue":"65"
      },
      "replacementValue":{
        "stringValue":"MEDIUM"
      }
    },
    {
      "min":{
        "integerValue":"66"
      },
      "max":{
        "integerValue":"100"
      },
      "replacementValue":{
        "stringValue":"HIGH"
      }
    }
  ]
}

Damit wird das folgende Verhalten definiert:

  • Ganzzahlwerte zwischen 1 und 30 werden maskiert, indem sie durch LOW ersetzt werden.
  • Ganzzahlwerte zwischen 31 und 65, werden maskiert, indem sie durch MEDIUM ersetzt werden.
  • Ganzzahlwerte zwischen 66 und 100 werden maskiert, indem sie durch HIGH ersetzt werden.

Weitere Informationen zum Konzept des Bucketings finden Sie unter Generalisierung und Bucketing.

replaceWithInfoTypeConfig

Bei Angabe von replaceWithInfoTypeConfig wird jeder übereinstimmende Wert durch den Namen des infoType ersetzt. Die replaceWithInfoTypeConfig-Meldung hat keine Argumente. Allein dadurch, dass sie angegeben wird, wird ihre Transformation aktiviert.

Angenommen, Sie haben replaceWithInfoTypeConfig für alle infoTypes EMAIL_ADDRESS angegeben und der folgende String wird an Cloud DLP gesendet:

My name is Alicia Abernathy, and my email address is aabernathy@example.com.

Der zurückgegebene String sieht so aus:

My name is Alicia Abernathy, and my email address is EMAIL_ADDRESS.
timePartConfig

Wenn Sie timePartConfig für ein TimePartConfig-Objekt festlegen, wird ein Teil eines übereinstimmenden Werts beibehalten, der Werte für Date, Timestamp und TimeOfDay enthält. Das TimePartConfig-Objekt besteht aus einem partToExtract-Argument, das mit einem beliebigen Enum-Wert der Art TimePart festgelegt werden kann, einschließlich Jahr, Monat, Tag des Monats und so weiter.

Angenommen, Sie haben eine timePartConfig-Transformation konfiguriert, wofür Sie partToExtract auf YEAR festgelegt haben. Nachdem Sie die Daten in der ersten Spalte (siehe unten) an Cloud DLP gesendet haben, erhalten Sie die transformierten Werte in der zweiten Spalte:

Ursprüngliche Werte Transformierte Werte
9/21/1976 1976
6/7/1945 1945
1/20/2009 2009
7/4/1776 1776
8/1/1984 1984
4/21/1982 1982

Eintragstransformationen

Eintragstransformationen (das Objekt RecordTransformations) werden nur auf Werte innerhalb von Tabellendaten angewendet, die als spezifischer infoType gekennzeichnet sind. Innerhalb von RecordTransformations gibt es zwei Unterkategorien von Transformationen:

  • fieldTransformations[]: Transformationen, die verschiedene Feldtransformationen anwenden.
  • recordSuppressions[]: Regeln, die festlegen, welche Einträge vollständig unterdrückt werden. Einträge, die mit einer Unterdrückungsregel in recordSuppressions[] übereinstimmen, werden in der Ausgabe ausgelassen.

Feldtransformationen

Jedes FieldTransformation-Objekt enthält drei Argumente:

  • fields: Ein oder mehrere Eingabefelder (FieldID-Objekte), auf die die Transformation angewendet werden soll.
  • condition: Eine Bedingung (ein RecordCondition-Objekt), die als wahr ausgewertet werden muss, damit die Transformation angewendet wird. Zum Beispiel: Eine Bucket-Transformation nur dann auf eine Altersspalte eines Eintrags anwenden, wenn sich die Postleitzahlenspalte für denselben Eintrag in einem bestimmten Bereich befindet. Oder: Ein Feld nur dann entfernen, wenn das Geburtsdatumsfeld das Alter einer Person auf 85 oder höher setzt.
  • Eines der folgenden zwei Argumente des Transformationstyps. Eines davon muss angegeben werden:

Einträge unterdrücken

Zusätzlich zum Anwenden von Transformationen auf Felddaten können Sie Cloud DLP auch anweisen, Daten einfach durch Unterdrückung von Einträgen zu de-identifizieren, wenn bestimmte Unterdrückungsbedingungen als wahr ausgewertet werden. Sie können sowohl Feldtransformationen als auch Eintragsunterdrückungen in derselben Anfrage anwenden.

Sie legen die recordSuppressions-Meldung des Objekts RecordTransformations auf ein Array von einem oder mehreren RecordSuppression-Objekten fest.

Jedes RecordSuppression-Objekt enthält ein einzelnes RecordCondition-Objekt, das wiederum ein einzelnes Expressions-Objekt enthält.

Ein Expressions-Objekt enthält:

  • logicalOperator: Einer der Enum-Typen LogicalOperator.
  • conditions: Ein Conditions-Objekt, das ein Array aus einem oder mehreren Condition-Objekten enthält. Unter Condition ist ein Vergleich zwischen einem Feldwert und einem anderen Wert zu verstehen, die beide vom Typ string, boolean, integer, double, Timestamp oder TimeofDay sind.

Wenn der Vergleich als wahr ausgewertet wird, wird der Eintrag unterdrückt und umgekehrt. Wenn die verglichenen Werte nicht vom selben Typ sind, wird eine Warnung ausgegeben und die Bedingung als falsch ausgewertet.