민감한 정보 익명화

민감한 정보 보호는 테이블과 같은 컨테이너 구조에 저장된 텍스트를 포함한 텍스트 콘텐츠의 민감한 정보를 익명화할 수 있습니다. 익명화는 데이터에서 식별 정보를 삭제하는 프로세스입니다. API는 개인 식별 정보(PII)와 같은 민감한 정보를 감지한 다음 익명화 변환을 사용하여 데이터를 마스킹, 삭제하거나 다른 방법으로 알아보기 어렵게 만듭니다. 예를 들어 익명화 기술에는 다음이 포함될 수 있습니다.

  • 전체 또는 일부 문자를 별표(*) 또는 해시(#)와 같은 기호로 바꿔 민감한 정보 마스킹
  • 각 민감한 정보 인스턴스를 토큰 또는 서로게이트 문자열로 바꿉니다.
  • 무작위로 생성되거나 사전 결정된 키를 사용하여 민감한 정보를 암호화 및 대체

HTTPS 기반 JSON, CLI 및 민감한 정보 보호 클라이언트 라이브러리를 사용하는 여러 프로그래밍 언어를 통해 API에 정보를 제공할 수 있습니다. CLI를 설정하려면 빠른 시작을 참조하세요. JSON 형식의 정보 제출에 대한 자세한 내용은 JSON 빠른 시작을 참조하세요.

API 개요

민감한 정보를 익명화하려면 민감한 정보 보호의 content.deidentify 메서드를 사용합니다.

익명화 API 호출에는 세 부분이 있습니다.

  • 검사할 데이터: 검사할 API에 대한 문자열 또는 테이블 구조(ContentItem 객체).
  • 검사할 대상: 찾을 데이터의 유형(즉, infoType), 특정 가능성 기준을 초과한 결과를 필터링할지 여부, 특정 수 이하의 결과만 반환할지 여부와 같은 감지 구성 정보 (InspectConfig)

    InspectConfig 객체에 스캔할 infoType을 포함해야 합니다. 그렇지 않으면 민감한 정보 보호는 기본 infoType 집합 (ALL_BASIC)을 스캔하며, 이 중 일부는 필요하지 않을 수 있습니다. 필요하지 않은 infoType을 스캔하면 요청에 불필요한 지연 시간이 추가될 수 있습니다.

    요청에 InspectConfig 객체가 필요합니다. 단, 한 가지 예외가 있습니다. 자세한 내용은 이 페이지의 기록 변환을 참고하세요.

  • 검사 결과의 처리 방법: 민감한 정보를 익명화할 방법을 정의하는 구성 정보(DeidentifyConfig). 이 인수에 대해서는 다음 섹션에서 더 자세히 다룹니다.

API는 사용자가 제공한 것과 동일한 항목을 동일한 형식으로 반환하지만 기준에 따라 민감한 정보를 포함한 것으로 식별된 모든 텍스트는 익명화됩니다.

감지 기준 지정

정보 유형(즉, 'infoType') 감지기는 민감한 정보 보호가 민감한 정보를 찾는 데 사용하는 메커니즘입니다.

민감한 정보 보호에는 여러 종류의 infoType 감지기가 있습니다. 이러한 모든 감지기를 요약하면 다음과 같습니다.

  • 기본 제공 infoType 감지기는 민감한 정보 보호에 기본 제공된 감지기입니다. 여기에는 전역적으로 적용 가능한 데이터 유형은 물론 국가 또는 리전별 민감한 정보 유형에 대한 감지기가 포함됩니다.
  • 커스텀 infoType 감지기는 개발자가 직접 만드는 감지기입니다. 커스텀 infoType 감지기에는 다음과 같은 세 가지 종류가 있습니다.
    • 일반 커스텀 사전 감지기는 민감한 정보 보호가 일치 항목을 검색하는 간단한 단어 목록입니다. 목록에 포함된 단어 또는 구문의 수가 최대 수만 개 수준인 경우 일반 커스텀 사전 감지기를 사용합니다. 단어 목록이 크게 바뀔 일이 없는 경우 일반 커스텀 사전 감지기가 유리합니다.
    • 저장된 커스텀 사전 감지기는 민감한 정보 보호에서 Cloud Storage 또는 BigQuery에 저장된 대량의 단어 또는 구문 목록을 사용하여 생성합니다. 목록에 포함된 단어 또는 구문의 수가 최대 수천만 개 수준으로 많은 경우 저장된 커스텀 사전 감지기를 사용합니다.
    • 정규 표현식(정규식) 감지기를 사용 설정하면 민감한 정보 보호에서 정규 표현식 패턴을 기준으로 일치 항목을 감지할 수 있습니다.

또한 민감한 정보 보호에는 다음을 사용하여 스캔 결과를 세부 조정할 수 있게 해주는 검사 규칙 개념이 포함되어 있습니다.

  • 제외 규칙은 기본 제공 또는 커스텀 infoType 감지기에 규칙을 추가하여 반환되는 결과의 수를 줄일 수 있게 해줍니다.
  • 핫워드 규칙을 사용하면 기본 제공 또는 커스텀 infoType 감지기에 규칙을 추가하여 반환되는 결과의 양을 늘리거나 가능성 값을 변경할 수 있습니다.

익명화 변환

익명화 구성(DeidentifyConfig)을 설정할 때는 변환을 하나 이상 지정해야 합니다. 변환에는 두 가지 카테고리가 있습니다.

  • InfoTypeTransformations: 제출된 텍스트 내에서 특정 infoType으로 식별된 값에만 적용되는 변환
  • RecordTransformations: 제출된 테이블 형식 텍스트 데이터 내에서 특정 infoType으로 식별된 값 또는 테이블 형식 데이터의 전체 열에만 적용되는 변환

InfoType 변환

요청당 하나 이상의 infoType 변환을 지정할 수 있습니다. 각 InfoTypeTransformation 객체 내에서 다음 두 가지를 모두 지정합니다.

infoType 지정은 선택사항이지만 InspectConfig 인수에 최소 하나의 infoType을 지정하지 않을 경우 제공된 변환이 없는 모든 기본 제공 infoType에 변환이 적용됩니다. 성능 저하와 비용 증가를 유발할 수 있으므로 이는 권장되지 않습니다.

기본 변환

특정 infoType에만 적용하든 전체 텍스트 문자열에 적용하든 관계없이 입력에 적용할 하나 이상의 기본 변환을 지정해야 합니다. 다음 섹션에서는 사용할 수 있는 변환 메서드의 예시를 설명합니다. 민감한 정보 보호에서 제공하는 모든 변환 메서드의 목록은 변환 참조를 확인하세요.

replaceConfig

replaceConfigReplaceValueConfig 객체로 설정하면 일치하는 입력 값이 지정한 값으로 대체됩니다.

예를 들어 모든 EMAIL_ADDRESS infoType에 replaceConfig[email-address]로 지정했고 다음 문자열이 민감한 정보 보호로 전송되었다고 가정해 보겠습니다.

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

다음과 같은 문자열이 반환됩니다.

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

여러 언어로 된 다음 JSON 예 및 코드는 API 요청을 작성하는 방법과 DLP API에서 반환하는 항목을 보여줍니다.

Python

Sensitive Data Protection의 클라이언트 라이브러리를 설치하고 사용하는 방법은 Sensitive Data Protection 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

from typing import List

import google.cloud.dlp


def deidentify_with_replace(
    project: str,
    input_str: str,
    info_types: List[str],
    replacement_str: str = "REPLACEMENT_STR",
) -> None:
    """Uses the Data Loss Prevention API to deidentify sensitive data in a
    string by replacing matched input values with a value you specify.
    Args:
        project: The Google Cloud project id to use as a parent resource.
        input_str: The string to deidentify (will be treated as text).
        info_types: A list of strings representing info types to look for.
        replacement_str: The string to replace all values that match given
            info types.
    Returns:
        None; the response from the API is printed to the terminal.
    """

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

    # Convert the project id into a full resource id.
    parent = f"projects/{project}/locations/global"

    # 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": {
                        "replace_config": {
                            "new_value": {"string_value": replacement_str}
                        }
                    }
                }
            ]
        }
    }

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

    # Call the API
    response = dlp.deidentify_content(
        request={
            "parent": parent,
            "deidentify_config": deidentify_config,
            "inspect_config": inspect_config,
            "item": item,
        }
    )

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

Java

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


import com.google.cloud.dlp.v2.DlpServiceClient;
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.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.ReplaceValueConfig;
import com.google.privacy.dlp.v2.Value;

public class DeIdentifyWithReplacement {

  public static void main(String[] args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String textToInspect =
        "My name is Alicia Abernathy, and my email address is aabernathy@example.com.";
    deIdentifyWithReplacement(projectId, textToInspect);
  }

  // Inspects the provided text.
  public static void deIdentifyWithReplacement(String projectId, String textToRedact) {
    // 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 the content to be inspected.
      ContentItem item = ContentItem.newBuilder().setValue(textToRedact).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("EMAIL_ADDRESS").build();
      InspectConfig inspectConfig = InspectConfig.newBuilder().addInfoTypes(infoType).build();
      // Specify replacement string to be used for the finding.
      ReplaceValueConfig replaceValueConfig =
          ReplaceValueConfig.newBuilder()
              .setNewValue(Value.newBuilder().setStringValue("[email-address]").build())
              .build();
      // Define type of deidentification as replacement.
      PrimitiveTransformation primitiveTransformation =
          PrimitiveTransformation.newBuilder().setReplaceConfig(replaceValueConfig).build();
      // Associate deidentification type with info type.
      InfoTypeTransformation transformation =
          InfoTypeTransformation.newBuilder()
              .addInfoTypes(infoType)
              .setPrimitiveTransformation(primitiveTransformation)
              .build();
      // Construct the configuration for the Redact request and list all desired transformations.
      DeidentifyConfig redactConfig =
          DeidentifyConfig.newBuilder()
              .setInfoTypeTransformations(
                  InfoTypeTransformations.newBuilder().addTransformations(transformation))
              .build();

      // Construct the Redact request to be sent by the client.
      DeidentifyContentRequest request =
          DeidentifyContentRequest.newBuilder()
              .setParent(LocationName.of(projectId, "global").toString())
              .setItem(item)
              .setDeidentifyConfig(redactConfig)
              .setInspectConfig(inspectConfig)
              .build();

      // Use the client to send the API request.
      DeidentifyContentResponse response = dlp.deidentifyContent(request);

      // Parse the response and process results
      System.out.println("Text after redaction: " + response.getItem().getValue());
    } catch (Exception e) {
      System.out.println("Error during inspectString: \n" + e.toString());
    }
  }
}

REST

JSON과 함께 DLP API를 사용하는 데 대한 자세한 내용은 JSON 빠른 시작을 참조하세요.

JSON 입력:

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 출력:

{
  "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

redactConfig를 지정하면 지정된 값을 완전히 삭제하는 방식으로 값이 수정됩니다. redactConfig 메시지는 인수가 없으며 지정하면 변환이 사용 설정됩니다.

예를 들어 모든 EMAIL_ADDRESS infoType에 redactConfig를 지정했고 다음 문자열이 민감한 정보 보호로 전송되었다고 가정해 보겠습니다.

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

다음과 같은 문자열이 반환됩니다.

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

다음 예시는 API 요청을 작성하는 방법과 DLP API가 반환하는 항목을 보여줍니다.

C#

Sensitive Data Protection의 클라이언트 라이브러리를 설치하고 사용하는 방법은 Sensitive Data Protection 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


using System;
using System.Collections.Generic;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;

public class DeidentifyDataUsingRedactWithMatchedInputValues
{
    public static DeidentifyContentResponse Deidentify(
        string projectId,
        string text,
        IEnumerable<InfoType> infoTypes = null)
    {
        // Instantiate the client.
        var dlp = DlpServiceClient.Create();

        // Construct inspect config.
        var inspectConfig = new InspectConfig
        {
            InfoTypes = { infoTypes ?? new InfoType[] { new InfoType { Name = "EMAIL_ADDRESS" } } },
        };

        // Construct redact config.
        var redactConfig = new RedactConfig();

        // Construct deidentify config using redact config.
        var deidentifyConfig = new DeidentifyConfig
        {
            InfoTypeTransformations = new InfoTypeTransformations
            {
                Transformations =
                {
                    new InfoTypeTransformations.Types.InfoTypeTransformation
                    {
                        PrimitiveTransformation = new PrimitiveTransformation
                        {
                            RedactConfig = redactConfig
                        }
                    }
                }
            }
        };

        // Construct a request.
        var request = new DeidentifyContentRequest
        {
            ParentAsLocationName = new LocationName(projectId, "global"),
            DeidentifyConfig = deidentifyConfig,
            InspectConfig = inspectConfig,
            Item = new ContentItem { Value = text }
        };

        // Call the API.
        var response = dlp.DeidentifyContent(request);

        // Check the deidentified content.
        Console.WriteLine($"Deidentified content: {response.Item.Value}");
        return response;
    }
}

Go

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import (
	"context"
	"fmt"
	"io"

	dlp "cloud.google.com/go/dlp/apiv2"
	"cloud.google.com/go/dlp/apiv2/dlppb"
)

// deidentifyWithRedact de-identify the data by redacting with matched input values
func deidentifyWithRedact(w io.Writer, projectID, inputStr string, infoTypeNames []string) error {
	// projectID := "my-project-id"
	// inputStr := "My name is Alicia Abernathy, and my email address is aabernathy@example.com."
	// infoTypeNames := []string{"EMAIL_ADDRESS"}

	ctx := context.Background()

	// Initialize a client once and reuse it to send multiple requests. Clients
	// are safe to use across goroutines. When the client is no longer needed,
	// call the Close method to cleanup its resources.
	client, err := dlp.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("dlp.NewClient: %w", err)
	}

	// Closing the client safely cleans up background resources.
	defer client.Close()

	// Specify the content to be inspected.
	contentItem := &dlppb.ContentItem{
		DataItem: &dlppb.ContentItem_Value{
			Value: inputStr,
		},
	}

	// 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
	var infoTypes []*dlppb.InfoType
	for _, it := range infoTypeNames {
		infoTypes = append(infoTypes, &dlppb.InfoType{Name: it})
	}
	inspectConfig := &dlppb.InspectConfig{
		InfoTypes: infoTypes,
	}

	// Define type of de-identification.
	primitiveTransformation := &dlppb.PrimitiveTransformation{
		Transformation: &dlppb.PrimitiveTransformation_RedactConfig{
			RedactConfig: &dlppb.RedactConfig{},
		},
	}

	// Associate de-identification type with info type.
	transformation := &dlppb.InfoTypeTransformations_InfoTypeTransformation{
		InfoTypes:               infoTypes,
		PrimitiveTransformation: primitiveTransformation,
	}

	// Construct the configuration for the Redact request and list all desired transformations.
	redactConfig := &dlppb.DeidentifyConfig{
		Transformation: &dlppb.DeidentifyConfig_InfoTypeTransformations{
			InfoTypeTransformations: &dlppb.InfoTypeTransformations{
				Transformations: []*dlppb.InfoTypeTransformations_InfoTypeTransformation{
					transformation,
				},
			},
		},
	}

	// Create a configured request.
	req := &dlppb.DeidentifyContentRequest{
		Parent:           fmt.Sprintf("projects/%s/locations/global", projectID),
		DeidentifyConfig: redactConfig,
		InspectConfig:    inspectConfig,
		Item:             contentItem,
	}

	// Send the request.
	resp, err := client.DeidentifyContent(ctx, req)
	if err != nil {
		return err
	}

	// Print the result.
	fmt.Fprintf(w, "output: %v", resp.GetItem().GetValue())
	return nil
}

Java

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


import com.google.cloud.dlp.v2.DlpServiceClient;
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.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.RedactConfig;

public class DeIdentifyWithRedaction {

  public static void main(String[] args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String textToInspect =
        "My name is Alicia Abernathy, and my email address is aabernathy@example.com.";
    deIdentifyWithRedaction(projectId, textToInspect);
  }

  // Inspects the provided text.
  public static void deIdentifyWithRedaction(String projectId, String textToRedact) {
    // 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 the content to be inspected.
      ContentItem item = ContentItem.newBuilder().setValue(textToRedact).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("EMAIL_ADDRESS").build();
      InspectConfig inspectConfig = InspectConfig.newBuilder().addInfoTypes(infoType).build();
      // Define type of deidentification.
      PrimitiveTransformation primitiveTransformation =
          PrimitiveTransformation.newBuilder()
              .setRedactConfig(RedactConfig.getDefaultInstance())
              .build();
      // Associate deidentification type with info type.
      InfoTypeTransformation transformation =
          InfoTypeTransformation.newBuilder()
              .addInfoTypes(infoType)
              .setPrimitiveTransformation(primitiveTransformation)
              .build();
      // Construct the configuration for the Redact request and list all desired transformations.
      DeidentifyConfig redactConfig =
          DeidentifyConfig.newBuilder()
              .setInfoTypeTransformations(
                  InfoTypeTransformations.newBuilder().addTransformations(transformation))
              .build();

      // Construct the Redact request to be sent by the client.
      DeidentifyContentRequest request =
          DeidentifyContentRequest.newBuilder()
              .setParent(LocationName.of(projectId, "global").toString())
              .setItem(item)
              .setDeidentifyConfig(redactConfig)
              .setInspectConfig(inspectConfig)
              .build();

      // Use the client to send the API request.
      DeidentifyContentResponse response = dlp.deidentifyContent(request);

      // Parse the response and process results
      System.out.println("Text after redaction: " + response.getItem().getValue());
    } catch (Exception e) {
      System.out.println("Error during inspectString: \n" + e.toString());
    }
  }
}

Node.js

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

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

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

// TODO(developer): Replace these variables before running the sample.
// const projectId = "your-project-id";

// The string to deidentify
// const string =
//   'My name is Alicia Abernathy, and my email address is aabernathy@example.com.';

// The infoTypes of information to match
// See https://cloud.google.com/dlp/docs/concepts-infotypes for more information
// about supported infoTypes.
// const infoTypes = [{name: 'EMAIL_ADDRESS'}];

async function deIdentifyRedaction() {
  // Construct deidentify configuration
  const deidentifyConfig = {
    infoTypeTransformations: {
      transformations: [
        {
          infoTypes: infoTypes,
          primitiveTransformation: {
            redactConfig: {},
          },
        },
      ],
    },
  };

  // Construct inspect configuration
  const inspectConfig = {
    infoTypes: infoTypes,
  };

  // Construct Item
  const item = {
    value: string,
  };

  // Combine configurations into a request for the service.
  const request = {
    parent: `projects/${projectId}/locations/global`,
    item,
    deidentifyConfig,
    inspectConfig,
  };

  // Send the request and receive response from the service
  const [response] = await dlp.deidentifyContent(request);

  // Print the results
  console.log(`Text after redaction: ${response.item.value}`);
}

deIdentifyRedaction();

PHP

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\DeidentifyContentRequest;
use Google\Cloud\Dlp\V2\InfoType;
use Google\Cloud\Dlp\V2\InfoTypeTransformations;
use Google\Cloud\Dlp\V2\InfoTypeTransformations\InfoTypeTransformation;
use Google\Cloud\Dlp\V2\InspectConfig;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;
use Google\Cloud\Dlp\V2\RedactConfig;

/**
 * De-identify data: Redacting with matched input values
 * Uses the Data Loss Prevention API to de-identify sensitive data in a string by redacting matched input values.
 *
 * @param string $callingProjectId      The Google Cloud project id to use as a parent resource.
 * @param string $textToInspect         The string to deidentify (will be treated as text).
 */
function deidentify_redact(
    // TODO(developer): Replace sample parameters before running the code.
    string $callingProjectId,
    string $textToInspect = 'My name is Alicia Abernathy, and my email address is aabernathy@example.com.'

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

    // Specify the content to be de-identify.
    $contentItem = (new ContentItem())
        ->setValue($textToInspect);

    // Specify the type of info the inspection will look for.
    $infoType = (new InfoType())
        ->setName('EMAIL_ADDRESS');
    $inspectConfig = (new InspectConfig())
        ->setInfoTypes([$infoType]);

    // Define type of de-identification.
    $primitiveTransformation = (new PrimitiveTransformation())
        ->setRedactConfig(new RedactConfig());

    // Associate de-identification type with info type.
    $transformation = (new InfoTypeTransformation())
        ->setInfoTypes([$infoType])
        ->setPrimitiveTransformation($primitiveTransformation);

    // Construct the configuration for the Redact request and list all desired transformations.
    $deidentifyConfig = (new DeidentifyConfig())
        ->setInfoTypeTransformations((new InfoTypeTransformations())
            ->setTransformations([$transformation]));

    $parent = "projects/$callingProjectId/locations/global";

    // Run request
    $deidentifyContentRequest = (new DeidentifyContentRequest())
        ->setParent($parent)
        ->setDeidentifyConfig($deidentifyConfig)
        ->setInspectConfig($inspectConfig)
        ->setItem($contentItem);
    $response = $dlp->deidentifyContent($deidentifyContentRequest);

    // Print results
    printf('Text after redaction: %s', $response->getItem()->getValue());
}

Python

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

from typing import List

import google.cloud.dlp


def deidentify_with_redact(
    project: str,
    input_str: str,
    info_types: List[str],
) -> None:
    """Uses the Data Loss Prevention API to deidentify sensitive data in a
    string by redacting matched input values.
    Args:
        project: The Google Cloud project id to use as a parent resource.
        input_str: The string to deidentify (will be treated as text).
        info_types: A list of strings representing info types to look for.
    Returns:
        None; the response from the API is printed to the terminal.
    """

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

    # Convert the project id into a full resource id.
    parent = f"projects/{project}/locations/global"

    # 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": {"redact_config": {}}}]
        }
    }

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

    # Call the API
    response = dlp.deidentify_content(
        request={
            "parent": parent,
            "deidentify_config": deidentify_config,
            "inspect_config": inspect_config,
            "item": item,
        }
    )

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

REST

JSON 입력:

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 출력:

{
  "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

characterMaskConfigCharacterMaskConfig 객체로 설정하면 지정된 수의 문자를 고정된 문자로 대체하는 방식으로 문자열이 마스킹됩니다. 마스킹은 문자열의 시작 또는 끝부터 시작할 수 있습니다. 이 변환은 long 정수와 같은 숫자 유형에서도 작동합니다.

CharacterMaskConfig 객체에는 여러 가지 자체 인수가 있습니다.

  • maskingCharacter: 민감한 값의 각 문자를 마스킹하는 데 사용되는 문자. 예를 들어 별표(*) 또는 해시(#)를 지정하여 신용카드 번호의 숫자와 같은 일련의 숫자를 마스킹할 수 있습니다.
  • numberToMask: 마스킹할 문자 수. 이 값을 설정하지 않으면 일치하는 모든 문자가 마스킹됩니다.
  • reverseOrder: 역순으로 문자를 마스킹할지 여부. reverseOrder를 true로 설정하면 일치하는 값의 문자가 값의 끝에서 시작 방향으로 마스킹됩니다. false로 설정하면 값의 시작 부분부터 마스킹이 시작됩니다.
  • charactersToIgnore[]: 값을 마스킹할 때 건너뛸 하나 이상의 문자. 예를 들어 전화번호를 마스킹할 때 하이픈을 그대로 두려면 여기에 하이픈을 지정합니다. 또한 마스킹할 때 무시할 공통 문자 그룹(CharsToIgnore)을 지정할 수도 있습니다.

예를 들어 '.' 및 '@' 문자를 제외하고 EMAIL_ADDRESS infoType에 대해 '#'을 사용하여 마스킹하도록 characterMaskConfig를 설정했다고 가정해 보겠습니다. 다음 문자열이 민감한 정보 보호로 전송되는 경우

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

다음과 같은 문자열이 반환됩니다.

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

다음은 DLP API를 사용하여 마스킹 기술로 민감한 정보를 익명화하는 방법을 보여주는 예시입니다.

Java

Sensitive Data Protection의 클라이언트 라이브러리를 설치하고 사용하는 방법은 Sensitive Data Protection 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


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.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import java.io.IOException;
import java.util.Arrays;

public class DeIdentifyWithMasking {

  public static void main(String[] args) throws Exception {
    // 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()
              .setCharacterMaskConfig(characterMaskConfig)
              .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(LocationName.of(projectId, "global").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

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

// 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 projectId = 'my-project-id';

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

async function deidentifyWithMask() {
  const request = {
    parent: `projects/${projectId}/locations/global`,
    deidentifyConfig: {
      infoTypeTransformations: {
        transformations: [
          {
            primitiveTransformation: {
              characterMaskConfig: {
                maskingCharacter: maskingCharacter,
                numberToMask: numberToMask,
              },
            },
          },
        ],
      },
    },
    item: item,
  };

  // Run deidentification request
  const [response] = await dlp.deidentifyContent(request);
  const deidentifiedItem = response.item;
  console.log(deidentifiedItem.value);
}

deidentifyWithMask();

Python

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

from typing import List

import google.cloud.dlp


def deidentify_with_mask(
    project: str,
    input_str: str,
    info_types: List[str],
    masking_character: str = None,
    number_to_mask: int = 0,
) -> None:
    """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.
        input_str: The string to deidentify (will be treated as text).
        info_types: A list of strings representing info types to look for.
            A full list of info type categories can be fetched from the API.
        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.
    """

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

    # Convert the project id into a full resource id.
    parent = f"projects/{project}/locations/global"

    # 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": input_str}

    # Call the API
    response = dlp.deidentify_content(
        request={
            "parent": parent,
            "deidentify_config": deidentify_config,
            "inspect_config": inspect_config,
            "item": item,
        }
    )

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

Go

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import (
	"context"
	"fmt"
	"io"

	dlp "cloud.google.com/go/dlp/apiv2"
	"cloud.google.com/go/dlp/apiv2/dlppb"
)

// 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: %w", err)
	}
	defer client.Close()
	// 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: fmt.Sprintf("projects/%s/locations/global", 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: %w", err)
	}
	// Print the result.
	fmt.Fprint(w, r.GetItem().GetValue())
	return nil
}

PHP

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

use Google\Cloud\Dlp\V2\CharacterMaskConfig;
use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\DeidentifyContentRequest;
use Google\Cloud\Dlp\V2\InfoType;
use Google\Cloud\Dlp\V2\InfoTypeTransformations;
use Google\Cloud\Dlp\V2\InfoTypeTransformations\InfoTypeTransformation;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;

/**
 * Deidentify sensitive data in a string by masking it with a character.
 *
 * @param string $callingProjectId The GCP Project ID to run the API call under
 * @param string $string           The string to deidentify
 * @param int    $numberToMask     (Optional) The maximum number of sensitive characters to mask in a match
 * @param string $maskingCharacter (Optional) The character to mask matching sensitive data with (defaults to "x")
 */
function deidentify_mask(
    string $callingProjectId,
    string $string,
    int $numberToMask = 0,
    string $maskingCharacter = 'x'
): void {
    // 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 = "projects/$callingProjectId/locations/global";

    // Run request
    $deidentifyContentRequest = (new DeidentifyContentRequest())
        ->setParent($parent)
        ->setDeidentifyConfig($deidentifyConfig)
        ->setItem($item);
    $response = $dlp->deidentifyContent($deidentifyContentRequest);

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

C#

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


using System;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;

public class DeidentifyWithMasking
{
    public static DeidentifyContentResponse Deidentify(string projectId, string text)
    {
        // Instantiate a client.
        var dlp = DlpServiceClient.Create();

        // Construct a request.
        var transformation = new InfoTypeTransformations.Types.InfoTypeTransformation
        {
            PrimitiveTransformation = new PrimitiveTransformation
            {
                CharacterMaskConfig = new CharacterMaskConfig
                {
                    MaskingCharacter = "*",
                    NumberToMask = 5,
                    ReverseOrder = false,
                }
            }
        };
        var request = new DeidentifyContentRequest
        {
            Parent = new LocationName(projectId, "global").ToString(),
            InspectConfig = new InspectConfig
            {
                InfoTypes =
                {
                    new InfoType { Name = "US_SOCIAL_SECURITY_NUMBER" }
                }
            },
            DeidentifyConfig = new DeidentifyConfig
            {
                InfoTypeTransformations = new InfoTypeTransformations
                {
                    Transformations = { transformation }
                }
            },
            Item = new ContentItem { Value = text }
        };

        // Call the API.
        var response = dlp.DeidentifyContent(request);

        // Inspect the results.
        Console.WriteLine($"Deidentified content: {response.Item.Value}");
        return response;
    }
}

REST

다음 JSON 예는 API 요청을 작성하는 방법과 DLP API에서 반환하는 항목을 보여줍니다.

JSON 입력:

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 출력:

{
  "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"
      }
    ]
  }
}

cryptoHashConfig

cryptoHashConfigCryptoHashConfig 객체로 설정하면 암호화 해시를 통해 서로게이트 값을 생성하는 방식으로 입력 값이 가명처리됩니다.

이 메서드는 암호화된 '다이제스트' 또는 해시 값으로 입력 값을 대체합니다. 다이제스트는 입력 값의 SHA-256 해시를 취해 계산됩니다. 해시를 만드는 데 사용되는 암호화 키는 CryptoKey 객체이며 크기는 32바이트 또는 64바이트여야 합니다.

메서드는 해시된 출력의 base64로 인코딩된 표현을 출력합니다. 현재 문자열과 정수 값만 해시가 가능합니다.

예를 들어 모든 EMAIL_ADDRESS infoType에 cryptoHashConfig를 지정했고 CryptoKey 객체가 무작위로 생성된 키 (TransientCryptoKey)로 구성되어 있다고 가정해 보겠습니다. 그러면 다음 문자열이 민감한 정보 보호로 전송됩니다.

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

암호화되어 생성되는 반환 문자열은 다음과 같습니다.

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

물론 16진수 문자열은 암호화되어 생성되며 여기 표시되는 것과는 다릅니다.

dateShiftConfig

dateShiftConfigDateShiftConfig 객체로 설정하면 무작위 일수만큼 날짜를 이동하는 방식으로 날짜 입력 값에 대한 날짜 이동이 수행됩니다.

날짜 이동 기법은 날짜 집합을 무작위로 이동하지만 순서와 기간은 보존합니다. 날짜 이동은 일반적으로 개인 또는 항목 컨텍스트에서 수행됩니다. 즉, 특정 개인의 모든 날짜를 동일한 교대 수당을 사용하여 이동하되, 각 개인에 별도의 교대 수당을 사용하고자 하는 경우입니다.

날짜 이동에 대한 자세한 내용은 날짜 이동 개념 주제를 참조하세요.

다음은 DLP API를 사용하여 날짜 이동으로 날짜를 익명화하는 방법을 보여주는 여러 언어로 된 샘플 코드입니다.

Java

Sensitive Data Protection의 클라이언트 라이브러리를 설치하고 사용하는 방법은 Sensitive Data Protection 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


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.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
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 main(String[] args) throws Exception {
    // 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(LocationName.of(projectId, "global").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

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

// 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 projectId = 'my-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};
};

async function deidentifyWithDateShift() {
  // 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: `projects/${projectId}/locations/global`,
    deidentifyConfig: {
      recordTransformations: {
        fieldTransformations: [
          {
            fields: dateFields,
            primitiveTransformation: {
              dateShiftConfig: dateShiftConfig,
            },
          },
        ],
      },
    },
    item: tableItem,
  };

  // 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}`);
}

deidentifyWithDateShift();

Python

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import base64
import csv
from datetime import datetime
from typing import List

import google.cloud.dlp
from google.cloud.dlp_v2 import types


def deidentify_with_date_shift(
    project: str,
    input_csv_file: str = None,
    output_csv_file: str = None,
    date_fields: List[str] = None,
    lower_bound_days: int = None,
    upper_bound_days: int = None,
    context_field_id: str = None,
    wrapped_key: str = None,
    key_name: str = None,
) -> 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.
    """

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

    # Convert the project id into a full resource id.
    parent = f"projects/{project}/locations/global"

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

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

    f = []
    with open(input_csv_file) 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: str) -> dict:
        return {"name": header}

    def map_data(value: str) -> dict:
        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: str) -> dict:
        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:
        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: types.storage.FieldId) -> str:
        return header.name

    def write_data(data: types.storage.Value) -> str:
        return data.string_value or "{}/{}/{}".format(
            data.date_value.month,
            data.date_value.day,
            data.date_value.year,
        )

    # Call the API
    response = dlp.deidentify_content(
        request={
            "parent": 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(f"Successfully saved date-shift output to {output_csv_file}")

Go

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import (
	"context"
	"fmt"
	"io"

	dlp "cloud.google.com/go/dlp/apiv2"
	"cloud.google.com/go/dlp/apiv2/dlppb"
)

// 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: %w", err)
	}
	defer client.Close()
	// Create a configured request.
	req := &dlppb.DeidentifyContentRequest{
		Parent: fmt.Sprintf("projects/%s/locations/global", 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: %w", err)
	}
	// Print the result.
	fmt.Fprint(w, r.GetItem().GetValue())
	return nil
}

PHP

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

use DateTime;
use Exception;
use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
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\DeidentifyContentRequest;
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;

/**
 * Deidentify dates in a CSV file by pseudorandomly shifting them.
 * 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.
 *
 * @param string $callingProjectId  The GCP Project ID to run the API call under
 * @param string $inputCsvFile      The path to the CSV file to deidentify
 * @param string $outputCsvFile     The path to save the date-shifted CSV file to
 * @param string $dateFieldNames    The comma-separated list of (date) fields in the CSV file to date shift
 * @param int    $lowerBoundDays    The maximum number of days to shift a date backward
 * @param int    $upperBoundDays    The maximum number of days to shift a date forward
 * @param string $contextFieldName  (Optional) The column to determine date shift amount based on
 * @param string $keyName           (Optional) The encrypted ('wrapped') AES-256 key to use when shifting dates
 * @param string $wrappedKey        (Optional) The name of the Cloud KMS key used to encrypt (wrap) the AES-256 key
 */
function deidentify_dates(
    string $callingProjectId,
    string $inputCsvFile,
    string $outputCsvFile,
    string $dateFieldNames,
    int $lowerBoundDays,
    int $upperBoundDays,
    string $contextFieldName = '',
    string $keyName = '',
    string $wrappedKey = ''
): void {
    // 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 = "projects/$callingProjectId/locations/global";

    // Run request
    $deidentifyContentRequest = (new DeidentifyContentRequest())
        ->setParent($parent)
        ->setDeidentifyConfig($deidentifyConfig)
        ->setItem($item);
    $response = $dlp->deidentifyContent($deidentifyContentRequest);

    // 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#

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


using System;
using System.IO;
using System.Linq;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;
using Google.Protobuf;

public class DeidentifyWithDateShift
{
    public static DeidentifyContentResponse Deidentify(
        string projectId,
        string inputCsvFilePath,
        int lowerBoundDays,
        int upperBoundDays,
        string dateFields,
        string contextField,
        string keyName,
        string wrappedKey)
    {
        var hasKeyName = !string.IsNullOrEmpty(keyName);
        var hasWrappedKey = !string.IsNullOrEmpty(wrappedKey);
        var hasContext = !string.IsNullOrEmpty(contextField);
        bool allFieldsSet = hasKeyName && hasWrappedKey && hasContext;
        bool noFieldsSet = !hasKeyName && !hasWrappedKey && !hasContext;
        if (!(allFieldsSet || noFieldsSet))
        {
            throw new ArgumentException("Must specify ALL or NONE of: {contextFieldId, keyName, wrappedKey}!");
        }

        var dlp = DlpServiceClient.Create();

        // Read file
        var csvLines = File.ReadAllLines(inputCsvFilePath);
        var csvHeaders = csvLines[0].Split(',');
        var 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.TryParse(rowValue, out var parsedDate)
               ? new Value { DateValue = Google.Type.Date.FromDateTime(parsedDate) }
               : 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
        };

        dateShiftConfig.Context = new FieldId { Name = contextField };
        dateShiftConfig.CryptoKey = new CryptoKey
        {
            KmsWrapped = new KmsWrappedCryptoKey
            {
                WrappedKey = ByteString.FromBase64(wrappedKey),
                CryptoKeyName = keyName
            }
        };

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

        var response = dlp.DeidentifyContent(
            new DeidentifyContentRequest
            {
                Parent = new LocationName(projectId, "global").ToString(),
                DeidentifyConfig = deidConfig,
                Item = new ContentItem
                {
                    Table = new Table
                    {
                        Headers = { protoHeaders },
                        Rows = { protoRows }
                    }
                }
            });

        return response;
    }
}

cryptoReplaceFfxFpeConfig

cryptoReplaceFfxFpeConfigCryptoReplaceFfxFpeConfig 객체로 설정하면 입력 값을 토큰으로 대체하는 방식으로 입력 값이 가명처리됩니다. 이 토큰의 특성은 다음과 같습니다.

  • 암호화된 입력 값입니다.
  • 입력 값과 같은 길이
  • cryptoKey에 의해 지정된 암호화 키를 사용하는 형식 보존 암호화(FPE-FFX)를 FFX 모드에서 사용하여 계산됩니다.
  • alphabet에 의해 지정되는 문자로 구성됩니다. 유효한 옵션은 다음과 같습니다.
    • NUMERIC
    • HEXADECIMAL
    • UPPER_CASE_ALPHA_NUMERIC
    • ALPHA_NUMERIC

입력 값의 특성은 다음과 같습니다.

  • 최소 2자여야 합니다(또는 빈 문자열).
  • alphabet으로 지정된 문자로 구성되어야 합니다. alphabet은 2~95자로 구성될 수 있습니다. (95자로 된 alphabet은 US-ASCII 문자 집합에 인쇄 가능한 모든 문자를 포함합니다.)

민감한 정보 보호는 암호화 키를 사용하여 대체 토큰을 계산합니다. 이 키는 다음 세 가지 방법 중 하나로 제공합니다.

  • API 요청에 암호화되지 않은 상태로 삽입 이는 권장되지 않습니다.
  • Sensitive Data Protection을 생성하도록 요청
  • API 요청에 암호화된 상태로 삽입

API 요청에 키를 삽입하도록 선택한 경우 Cloud Key Management Service(Cloud KMS) 키를 사용하여 키를 만들고 래핑(암호화)해야 합니다. 반환된 값은 기본적으로 Base64 인코딩 문자열입니다. Sensitive Data Protection에서 이 값을 설정하려면 바이트 문자열로 디코딩해야 합니다. 다음 코드 스니펫은 여러 언어로 이 작업을 수행하는 방법을 보여줍니다. 엔드 투 엔드 예시는 이러한 스니펫 뒤에 제공됩니다.

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)

Cloud KMS를 사용한 데이터 암호화 및 복호화에 대한 자세한 내용은 데이터 암호화 및 복호화를 참조하세요.

설계상 FPE-FFX는 입력 텍스트의 길이와 문자 집합을 보존합니다. 즉, 인증과 초기화 벡터가 없어 출력 토큰에서 길이가 확장됩니다. AES-SIV와 같은 다른 방법은 이러한 더 강력한 보안을 제공하며 길이와 문자 집합 보존을 엄격하게 요구하지 않는 한 토큰화 사용 사례에 권장됩니다. 예를 들면 레거시 데이터 시스템의 이전 버전과의 호환성을 위해 사용됩니다.

다음은 민감한 정보 보호를 사용하여 입력 값을 토큰으로 대체해 민감한 정보를 익명화하는 방법을 보여주는 여러 언어로 작성된 샘플 코드입니다.

Java

Sensitive Data Protection의 클라이언트 라이브러리를 설치하고 사용하는 방법은 Sensitive Data Protection 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


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.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.util.Arrays;

public class DeIdentifyWithFpe {

  public static void main(String[] args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String textToDeIdentify = "I'm Gary and my SSN is 552096781";
    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(LocationName.of(projectId, "global").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

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

// 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 projectId = 'my-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';

async function deidentifyWithFpe() {
  // 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: `projects/${projectId}/locations/global`,
    deidentifyConfig: {
      infoTypeTransformations: {
        transformations: [
          {
            primitiveTransformation: {
              cryptoReplaceFfxFpeConfig: cryptoReplaceFfxFpeConfig,
            },
          },
        ],
      },
    },
    item: item,
  };

  // Run deidentification request
  const [response] = await dlp.deidentifyContent(request);
  const deidentifiedItem = response.item;
  console.log(deidentifiedItem.value);
}
deidentifyWithFpe();

Python

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import base64
from typing import List

import google.cloud.dlp


def deidentify_with_fpe(
    project: str,
    input_str: str,
    info_types: List[str],
    alphabet: str = None,
    surrogate_type: str = None,
    key_name: str = None,
    wrapped_key: str = None,
) -> 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.
        input_str: The string to deidentify (will be treated as text).
        info_types: A list of strings representing info types to look for.
        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.
    """

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

    # Convert the project id into a full resource id.
    parent = f"projects/{project}/locations/global"

    # The wrapped key is base64-encoded, but the library expects a binary
    # string, so decode it here.
    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": input_str}

    # Call the API
    response = dlp.deidentify_content(
        request={
            "parent": parent,
            "deidentify_config": deidentify_config,
            "inspect_config": inspect_config,
            "item": item,
        }
    )

    # Print results
    print(response.item.value)

Go

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import (
	"context"
	"encoding/base64"
	"fmt"
	"io"

	dlp "cloud.google.com/go/dlp/apiv2"
	"cloud.google.com/go/dlp/apiv2/dlppb"
)

// 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, kmsKeyName, wrappedAESKey, surrogateInfoType string) error {
	// projectID := "my-project-id"
	// input := "My SSN is 123456789"
	// infoTypeNames := []string{"US_SOCIAL_SECURITY_NUMBER"}
	// kmsKeyName := "projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME"
	// wrappedAESKey := "YOUR_ENCRYPTED_AES_256_KEY"
	// surrogateInfoType := "AGE"
	ctx := context.Background()
	client, err := dlp.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("dlp.NewClient: %w", err)
	}
	defer client.Close()
	// 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})
	}

	// Specify an encrypted AES-256 key and the name of the Cloud KMS key that encrypted it.
	kmsWrappedCryptoKey, err := base64.StdEncoding.DecodeString(wrappedAESKey)
	if err != nil {
		return err
	}

	// Create a configured request.
	req := &dlppb.DeidentifyContentRequest{
		Parent: fmt.Sprintf("projects/%s/locations/global", 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:    kmsWrappedCryptoKey,
													CryptoKeyName: kmsKeyName,
												},
											},
										},
										// 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: %w", err)
	}
	// Print the result.
	fmt.Fprint(w, r.GetItem().GetValue())
	return nil
}

PHP

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\CryptoKey;
use Google\Cloud\Dlp\V2\CryptoReplaceFfxFpeConfig;
use Google\Cloud\Dlp\V2\CryptoReplaceFfxFpeConfig\FfxCommonNativeAlphabet;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\DeidentifyContentRequest;
use Google\Cloud\Dlp\V2\InfoType;
use Google\Cloud\Dlp\V2\InfoTypeTransformations;
use Google\Cloud\Dlp\V2\InfoTypeTransformations\InfoTypeTransformation;
use Google\Cloud\Dlp\V2\KmsWrappedCryptoKey;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;

/**
 * Deidentify a string using Format-Preserving Encryption (FPE).
 *
 * @param string $callingProjectId  The GCP Project ID to run the API call under
 * @param string $string            The string to deidentify
 * @param string $keyName           The name of the Cloud KMS key used to encrypt (wrap) the AES-256 key
 * @param string $wrappedKey        The name of the Cloud KMS key use, encrypted with the KMS key in $keyName
 * @param string $surrogateTypeName (Optional) surrogate custom info type to enable reidentification
 */
function deidentify_fpe(
    string $callingProjectId,
    string $string,
    string $keyName,
    string $wrappedKey,
    string $surrogateTypeName = ''
): void {
    // 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 = "projects/$callingProjectId/locations/global";

    // Run request
    $deidentifyContentRequest = (new DeidentifyContentRequest())
        ->setParent($parent)
        ->setDeidentifyConfig($deidentifyConfig)
        ->setItem($content);
    $response = $dlp->deidentifyContent($deidentifyContentRequest);

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

C#

민감한 정보 보호의 클라이언트 라이브러리를 설치하고 사용하는 방법은 민감한 정보 보호 클라이언트 라이브러리를 참조하세요.

Sensitive Data Protection에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


using System;
using System.Collections.Generic;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;
using Google.Protobuf;
using static Google.Cloud.Dlp.V2.CryptoReplaceFfxFpeConfig.Types;

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

        var dlp = DlpServiceClient.Create();
        var response = dlp.DeidentifyContent(
            new DeidentifyContentRequest
            {
                Parent = new LocationName(projectId, "global").ToString(),
                InspectConfig = new InspectConfig
                {
                    InfoTypes = { infoTypes }
                },
                DeidentifyConfig = deidentifyConfig,
                Item = new ContentItem { Value = dataValue }
            });

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

민감한 정보 보호를 사용하여 CryptoReplaceFfxFpeConfig 변환 메서드를 통해 익명화된 민감한 정보를 재식별하는 방법을 보여주는 코드 샘플은 형식 보존 암호화: 재식별 예시를 참조하세요.

fixedSizeBucketingConfig

버케팅 변환(fixedSizeBucketingConfig와 bucketingConfig)은 숫자 데이터를 범위로 '버케팅'하여 마스킹하는 역할을 합니다. 결과 숫자 범위는 하한, 하이픈, 상한으로 구성되어 하이픈으로 연결된 문자열입니다.

fixedSizeBucketingConfigFixedSizeBucketingConfig 객체로 설정하면 입력 값이 고정된 크기 범위를 기반으로 버케팅됩니다. FixedSizeBucketingConfig 객체는 다음과 같이 구성됩니다.

  • lowerBound: 모든 버킷의 하한 값. 이 값보다 작은 값은 하나의 버킷으로 그룹화됩니다.
  • upperBound: 모든 버킷의 상한 값. 이 값보다 큰 값은 하나의 버킷으로 그룹화됩니다.
  • bucketSize: 최소 및 최대 버킷을 제외한 각 버킷의 크기.

예를 들어 lowerBound가 10으로 설정되고 upperBound가 89로 설정되고 bucketSize가 10으로 설정되는 경우 사용되는 버킷은 -10, 10-20, 20-30, 30-40, 40-50, 50-60, 60-70, 70-80, 80-89, 89+입니다.

버케팅 개념에 대한 자세한 내용은 일반화 및 버케팅을 참조하세요.

bucketingConfig

bucketingConfig 변환은 다른 버케팅 변환인 fixedSizeBucketingConfig에 비해 더 유연합니다. 상한 및 하한과 동일한 크기의 버킷을 만들기 위한 간격 값을 지정하는 대신 만들려는 각 버킷의 최댓값 및 최솟값을 지정합니다. 각 최댓값 및 최솟값 쌍의 유형은 동일해야 합니다.

bucketingConfigBucketingConfig 객체로 설정하면 커스텀 버킷이 지정됩니다. BucketingConfig 객체는 Bucket 객체의 buckets[] 배열로 구성됩니다. 각 Bucket 객체는 다음과 같이 구성됩니다.

  • min: 버킷 범위의 하한. 하한이 없는 버킷을 만들려면 이 값을 생략합니다.
  • max: 버킷 범위의 상한. 상한이 없는 버킷을 만들려면 이 값을 생략합니다.
  • replacementValue: 하한 및 상한 내에 속하는 값을 대체할 값. replacementValue를 제공하지 않으면 하이픈으로 연결된 min-max 범위가 대신 사용됩니다.

값이 정의된 범위를 벗어나는 경우 반환되는 TransformationSummary에 오류 메시지가 포함됩니다.

예를 들어 bucketingConfig 변환을 위한 다음 구성을 가정해 보겠습니다.

"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"
      }
    }
  ]
}

이는 다음 동작을 정의합니다.

  • 1에서 30 사이에 속하는 정수 값은 LOW로 대체되어 마스킹됩니다.
  • 31에서 65 사이에 속하는 정수 값은 MEDIUM으로 대체되어 마스킹됩니다.
  • 66에서 100 사이에 속하는 정수 값은 HIGH로 대체되어 마스킹됩니다.

버케팅 개념에 대한 자세한 내용은 일반화 및 버케팅을 참조하세요.

replaceWithInfoTypeConfig

replaceWithInfoTypeConfig를 지정하면 각 일치 값이 infoType의 이름으로 대체됩니다. replaceWithInfoTypeConfig 메시지는 인수가 없으며 지정하면 변환이 사용 설정됩니다.

예를 들어 모든 EMAIL_ADDRESS infoType에 replaceWithInfoTypeConfig를 지정했고 다음 문자열이 민감한 정보 보호로 전송되었다고 가정해 보겠습니다.

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

다음과 같은 문자열이 반환됩니다.

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

timePartConfigTimePartConfig 객체로 설정하면 Date, Timestamp, TimeOfDay 값이 포함된 일치 값 부분이 보존됩니다. TimePartConfig 객체는 partToExtract 인수로 구성되며 이 인수는 연, 월, 일을 포함한 모든 TimePart 열거 값으로 설정할 수 있습니다.

예를 들어 partToExtractYEAR로 설정하여 timePartConfig 변환을 구성했다고 가정해 보겠습니다. 아래의 첫 번째 열 데이터를 민감한 정보 보호로 보내면 두 번째 열의 변환된 값이 됩니다.

원래 값 변환된 값
9/21/1976 1976
6/7/1945 1945
1/20/2009 2009
7/4/1776 1776
8/1/1984 1984
4/21/1982 1982

레코드 변환

레코드 변환(RecordTransformations 객체)은 특정 infoType으로 식별되는 테이블 형식 데이터 내의 값에만 적용됩니다. RecordTransformations 내에는 두 가지 추가 하위 변환 카테고리가 있습니다.

  • fieldTransformations[]: 다양한 필드 변환에 적용되는 변환.
  • recordSuppressions[]: 완전히 억제되는 레코드를 정의하는 규칙. recordSuppressions[] a내의 억제 규칙과 일치하는 레코드는 출력에서 생략됩니다.

필드 변환

FieldTransformation 객체에는 세 가지 인수가 포함됩니다.

  • fields: 변환을 적용할 하나 이상의 입력 필드(FieldID 객체).
  • condition: 변환이 적용되려면 true로 계산되어야 하는 조건(RecordCondition 객체). 예를 들어 동일한 레코드의 우편번호 열이 특정 범위 내에 있는 경우에만 레코드의 연령 열에 버킷 변환을 적용합니다. 또는 생일 필드에 따라 그 사람의 연령이 85세 이상인 경우에만 필드를 수정합니다.
  • 다음 두 가지 변환 유형 인수 중 하나. 하나를 필수적으로 지정해야 합니다.

    • infoTypeTransformations: 필드 콘텐츠를 자유 텍스트로 취급하고 InfoType.과 일치하는 콘텐츠에만 PrimitiveTransformation을 적용합니다. 이러한 변환은 이 주제의 앞부분에 설명되어 있습니다.
    • primitiveTransformation: 지정된 기본 변환(PrimitiveTransformation 객체)을 전체 필드에 적용합니다. 이러한 변환은 이 주제의 앞부분에 설명되어 있습니다.

      RecordTransformations 객체에 infoTypeTransformations가 아닌 primitiveTransformation만 포함되어 있으면 요청에 InspectConfig 객체를 포함할 필요가 없습니다. 이렇게 하면 민감한 정보 보호에서 이를 무시합니다.

필드 변환 예시

다음 예시에서는 필드 변환 두 개에서 projects.content.deidentify 요청을 보냅니다.

  • 첫 번째 필드 변환은 처음 두 열(column1column2)에 적용됩니다. 변환 유형은 primitiveTransformation 객체(특히 CryptoDeterministicConfig)이므로 민감한 정보 보호는 전체 필드를 변환합니다.

  • 두 번째 필드 변환은 세 번째 열(column3)에 적용됩니다. 변환 유형은 infoTypeTransformations 객체이므로 민감한 정보 보호는 기본 변환(특히, ReplaceWithInfoTypeConfig)을 검사 구성에 설정된 infoType과 일치하는 콘텐츠에만 적용합니다.

요청 데이터를 사용하기 전에 다음을 바꿉니다.

  • PROJECT_ID: Google Cloud 프로젝트 ID입니다. 프로젝트 ID는 my-project 같은 영숫자 문자열입니다.

HTTP 메서드 및 URL:

POST https://dlp.googleapis.com/v2/projects/PROJECT_ID/content:deidentify

JSON 요청 본문:

{
  "item": {
    "table": {
      "headers": [
        {
          "name": "column1"
        },
        {
          "name": "column2"
        },
        {
          "name": "column3"
        }
      ],
      "rows": [
        {
          "values": [
            {
              "stringValue": "Example string 1"
            },
            {
              "stringValue": "Example string 2"
            },
            {
              "stringValue": "My email address is dani@example.org"
            }
          ]
        },
        {
          "values": [
            {
              "stringValue": "Example string 1"
            },
            {
              "stringValue": "Example string 3"
            },
            {
              "stringValue": "My email address is cruz@example.org"
            }
          ]
        }
      ]
    }
  },
  "deidentifyConfig": {
    "recordTransformations": {
      "fieldTransformations": [
        {
          "fields": [
            {
              "name": "column1"
            },
            {
              "name": "column2"
            }
          ],
          "primitiveTransformation": {
            "cryptoDeterministicConfig": {
              "cryptoKey": {
                "unwrapped": {
                  "key": "YWJjZGVmZ2hpamtsbW5vcA=="
                }
              }
            }
          }
        },
        {
          "fields": [
            {
              "name": "column3"
            }
          ],
          "infoTypeTransformations": {
            "transformations": [
              {
                "primitiveTransformation": {
                  "replaceWithInfoTypeConfig": {}
                }
              }
            ]
          }
        }
      ]
    }
  },
  "inspectConfig": {
    "infoTypes": [
      {
        "name": "EMAIL_ADDRESS"
      }
    ]
  }
}

요청을 보내려면 다음 옵션 중 하나를 펼칩니다.

다음과 비슷한 JSON 응답이 표시됩니다.

{
  "item": {
    "table": {
      "headers": [
        {
          "name": "column1"
        },
        {
          "name": "column2"
        },
        {
          "name": "column3"
        }
      ],
      "rows": [
        {
          "values": [
            {
              "stringValue": "AWttmGlln6Z2MFOMqcOzDdNJS52XFxOOZsg0ckDeZzfc"
            },
            {
              "stringValue": "AUBTE+sQB6eKZ5iD3Y0Ss682zANXbijuFl9KL9ExVOTF"
            },
            {
              "stringValue": "My email address is [EMAIL_ADDRESS]"
            }
          ]
        },
        {
          "values": [
            {
              "stringValue": "AWttmGlln6Z2MFOMqcOzDdNJS52XFxOOZsg0ckDeZzfc"
            },
            {
              "stringValue": "AU+oD2pnqUDTLNItE8RplY3E0fTHeO4rZkX4GeFHN2CI"
            },
            {
              "stringValue": "My email address is [EMAIL_ADDRESS]"
            }
          ]
        }
      ]
    }
  },
  "overview": {
    "transformedBytes": "96",
    "transformationSummaries": [
      {
        "field": {
          "name": "column1"
        },
        "results": [
          {
            "count": "2",
            "code": "SUCCESS"
          }
        ],
        "fieldTransformations": [
          {
            "fields": [
              {
                "name": "column1"
              },
              {
                "name": "column2"
              }
            ],
            "primitiveTransformation": {
              "cryptoDeterministicConfig": {
                "cryptoKey": {
                  "unwrapped": {
                    "key": "YWJjZGVmZ2hpamtsbW5vcA=="
                  }
                }
              }
            }
          }
        ],
        "transformedBytes": "32"
      },
      {
        "field": {
          "name": "column2"
        },
        "results": [
          {
            "count": "2",
            "code": "SUCCESS"
          }
        ],
        "fieldTransformations": [
          {
            "fields": [
              {
                "name": "column1"
              },
              {
                "name": "column2"
              }
            ],
            "primitiveTransformation": {
              "cryptoDeterministicConfig": {
                "cryptoKey": {
                  "unwrapped": {
                    "key": "YWJjZGVmZ2hpamtsbW5vcA=="
                  }
                }
              }
            }
          }
        ],
        "transformedBytes": "32"
      },
      {
        "infoType": {
          "name": "EMAIL_ADDRESS",
          "sensitivityScore": {
            "score": "SENSITIVITY_MODERATE"
          }
        },
        "field": {
          "name": "column3"
        },
        "results": [
          {
            "count": "2",
            "code": "SUCCESS"
          }
        ],
        "fieldTransformations": [
          {
            "fields": [
              {
                "name": "column3"
              }
            ],
            "infoTypeTransformations": {
              "transformations": [
                {
                  "primitiveTransformation": {
                    "replaceWithInfoTypeConfig": {}
                  }
                }
              ]
            }
          }
        ],
        "transformedBytes": "32"
      }
    ]
  }
}

레코드 억제

필드 데이터에 변환 적용 이외에 특정 억제 조건이 true로 계산되는 경우 단순히 레코드를 억제하는 방법으로 데이터를 익명화하도록 민감한 정보 보호에 지시할 수도 있습니다. 같은 요청에서 필드 변환과 레코드 억제를 모두 적용할 수 있습니다.

RecordTransformations 객체의 recordSuppressions 메시지를 하나 이상의 RecordSuppression 객체 배열로 설정합니다.

RecordSuppression 객체에는 하나의 RecordCondition 객체가 포함되며, 이 객체에는 하나의 Expressions 객체가 포함됩니다.

Expressions 객체에는 다음이 포함됩니다.

  • logicalOperator: LogicalOperator 열거된 유형 중 하나.
  • conditions: Conditions 객체. 하나 이상의 Condition 객체의 배열이 포함됩니다. Condition은 둘 모두 string, boolean, integer, double, Timestamp, TimeofDay 유형인 필드 값과 다른 값의 비교입니다.

비교가 true로 계산되는 경우 레코드가 억제되고 그 반대도 마찬가지입니다. 비교되는 값의 유형이 같지 않은 경우 경고가 표시되고 조건은 false로 계산됩니다.

가역 변환

CryptoReplaceFfxFpeConfig 또는 CryptoDeterministicConfig infoType 변환을 사용하여 데이터를 익명화할 때는 원래 데이터 익명화를 위해 사용된 CryptoKey가 있는 한 데이터를 재식별화할 수 있습니다. 자세한 내용은 암호화 기반 토큰화 변환을 참조하세요.

발견 항목 수 제한

요청에서 발견 항목 수가 3,000개를 초과하면 민감한 정보 보호가 다음 메시지를 반환합니다.

Too many findings to de-identify. Retry with a smaller request.

민감한 정보 보호가 반환하는 발견 항목 목록은 요청에 있는 모든 발견 항목의 임의 하위 집합입니다. 모든 발견 항목을 가져오려면 요청을 작은 배치로 분할하세요.

다음 단계