Cloud Data Loss Prevention 개요

1. 개요

Cloud Data Loss Prevention (DLP)은 민감한 정보를 검색, 분류, 보호할 수 있도록 설계된 완전 관리형 서비스입니다. 이 Codelab에서는 Cloud DLP API의 기본 기능을 소개하고 데이터를 보호하는 다양한 방법을 보여줍니다.

실습할 내용

  • DLP를 사용하여 문자열과 파일에서 일치하는 정보 유형 검사
  • 익명화 기법을 익히고 DLP를 사용하여 데이터 익명화
  • 형식 보존 암호화 (FPE)를 사용하여 익명화된 데이터를 재식별하는 방법 알아보기
  • DLP를 사용하여 문자열과 이미지의 정보 유형 수정

필요한 항목

2. 설정

이 Codelab은 로컬 설치나 구성 없이 Google Cloud Platform에서 완전히 실행할 수 있습니다.

Cloud Shell

이 Codelab에서는 Cloud Shell을 통해 명령줄을 사용하여 다양한 클라우드 리소스와 서비스를 프로비저닝하고 관리합니다.

호환 프로젝트 저장소를 다운로드합니다.

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

프로젝트 코드를 다운로드한 후 samples 디렉터리로 변경하고 필요한 Node.js 패키지를 설치합니다.

cd samples && npm install

다음 gcloud 명령어를 사용하여 올바른 프로젝트를 설정합니다.

gcloud config set project [PROJECT_ID]

API 사용 설정

프로젝트에서 사용 설정해야 하는 API는 다음과 같습니다.

  • Cloud Data Loss Prevention API - 텍스트, 이미지, Google Cloud Platform 스토리지 저장소에서 민감한 개인 정보 보호 프래그먼트를 감지, 위험 분석, 익명화하는 방법을 제공합니다.
  • Cloud Key Management Service (KMS) API - Google Cloud KMS를 사용하면 고객이 암호화 키를 관리하고 해당 키로 암호화 작업을 수행할 수 있습니다.

다음 gcloud 명령어를 사용하여 필요한 API를 사용 설정합니다.

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

3. 문자열 및 파일 검사

이전 단계에서 다운로드한 프로젝트의 samples 디렉터리에는 Cloud DLP의 다양한 기능을 활용하는 여러 JavaScript 파일이 포함되어 있습니다. inspect.js은 제공된 문자열 또는 파일에서 민감한 정보 유형을 검사합니다.

이를 테스트하려면 string 옵션과 잠재적으로 민감한 정보가 포함된 샘플 문자열을 제공하면 됩니다.

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

출력은 일치하는 각 정보 유형에 대한 발견 항목을 알려줍니다. 여기에는 다음이 포함됩니다.

견적: 템플릿은 다음을 지정합니다.

InfoType: 문자열의 해당 부분에 대해 감지된 정보 유형입니다. 가능한 정보 유형의 전체 목록은 여기에서 확인할 수 있습니다. 기본적으로 inspect.js는 정보 유형 CREDIT_CARD_NUMBER, PHONE_NUMBER, EMAIL_ADDRESS만 검사합니다.

가능성: 결과는 일치할 가능성에 따라 분류됩니다. 가능성은 VERY_UNLIKELY부터 VERY_LIKELY까지의 범위에 해당합니다.

위 명령어 요청에 대한 결과는 다음과 같습니다.

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

마찬가지로 파일에서 정보 유형을 검사할 수 있습니다. 샘플 accounts.txt 파일을 확인하세요.

resources/accounts.txt

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

이번에는 파일 옵션을 사용하여 inspect.js를 다시 실행합니다.

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

결과:

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

어떤 종류의 쿼리든 가능성 또는 정보 유형별로 결과를 제한할 수 있습니다. 예를 들면 다음과 같습니다.

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

VERY_LIKELY를 최소 가능성으로 지정하면 VERY_LIKELY 미만의 일치 항목이 제외됩니다.

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

제한이 없는 전체 결과는 다음과 같습니다.

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

마찬가지로 확인할 정보 유형을 지정할 수 있습니다.

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

지정된 정보 유형이 발견되면 해당 정보 유형만 반환됩니다.

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

아래는 API를 사용하여 입력을 검사하는 비동기 함수입니다.

inspect.js

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

위의 파라미터에 제공된 인수는 요청 객체를 구성하는 데 사용됩니다. 그런 다음 해당 요청이 inspectContent 함수에 제공되어 다음과 같은 출력을 생성하는 응답을 얻습니다.

inspect.js

  // Construct item to inspect
  const item = {value: string};

  // Construct request
  const request = {
    parent: dlp.projectPath(callingProjectId),
    inspectConfig: {
      infoTypes: infoTypes,
      customInfoTypes: customInfoTypes,
      minLikelihood: minLikelihood,
      includeQuote: includeQuote,
      limits: {
        maxFindingsPerRequest: maxFindings,
      },
    },
    item: item,
  };
...
...
 const [response] = await dlp.inspectContent(request);

4. 익명화

Cloud DLP는 민감한 정보를 검사하고 감지하는 것 외에도 익명화를 수행할 수 있습니다. 익명화는 데이터에서 식별 정보를 삭제하는 프로세스입니다. API는 정보 유형에 따라 정의된 민감한 정보를 감지한 다음 익명화 변환을 사용하여 데이터를 마스킹, 삭제하거나 다른 방법으로 알아보기 어렵게 만듭니다.

deid.js는 여러 가지 방법으로 익명화를 보여줍니다. 가장 간단한 비식별화 방법은 마스크를 사용하는 것입니다.

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

마스크를 사용하면 API가 일치하는 정보 유형의 문자를 다른 문자(기본적으로 *)로 바꿉니다. 출력은 다음과 같습니다.

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

문자열의 이메일 주소는 난독화되었지만 임의의 주문 번호는 그대로 유지됩니다. (맞춤 정보 유형도 가능하지만 이 Codelab에서는 다루지 않습니다.)

DLP API를 사용하여 마스크로 익명화하는 함수를 살펴보겠습니다.

deid.js

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

다시 한번 말하지만 이러한 인수는 요청 객체를 구성하는 데 사용됩니다. 이번에는 deidentifyContent 함수에 제공됩니다.

deid.js

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

형식 보존 암호화로 익명화

DLP API는 암호화 키를 사용하여 민감한 정보 값을 암호화하는 기능도 제공합니다.

먼저 Cloud KMS를 사용하여 키링을 만듭니다.

gcloud kms keyrings create dlp-keyring --location global

이제 데이터를 암호화하는 데 사용할 키를 만들 수 있습니다.

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

DLP API는 생성한 KMS 키로 암호화된 래핑된 키를 허용합니다. 래핑될 임의의 문자열을 생성할 수 있습니다. 나중에 다시 식별하려면 다음이 필요합니다.

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

이제 KMS 키로 문자열을 암호화할 수 있습니다. 그러면 암호화된 문자열이 암호문으로 포함된 바이너리 파일이 생성됩니다.

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

이제 deid.js를 사용하여 암호화를 통해 아래 샘플 문자열의 전화번호를 익명화할 수 있습니다.

node deid.js deidFpe -c $GOOGLE_CLOUD_PROJECT \
"My client's cell is 9006492568" `base64 -w 0 ciphertext.bin` \
projects/${GOOGLE_CLOUD_PROJECT}/locations/global/keyRings/dlp-keyring/cryptoKeys/dlp-key \
-s PHONE_NUMBER

출력은 일치하는 정보 유형이 암호화된 문자열로 대체되고 -s 플래그로 표시된 정보 유형이 앞에 오는 문자열을 반환합니다.

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

문자열을 익명화하는 데 사용되는 함수를 살펴보겠습니다.

deid.js

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

인수는 cryptoReplaceFfxFpeConfig 객체를 구성하는 데 사용됩니다.

deid.js

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

cryptoReplaceFfxFpeConfig 객체는 deidentifyContent 함수를 통해 API에 대한 요청에 사용됩니다.

deid.js

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

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

데이터 재식별

데이터를 재식별하기 위해 DLP API는 이전 단계에서 만든 암호문을 사용합니다.

node deid.js reidFpe -c $GOOGLE_CLOUD_PROJECT \
"<YOUR_DEID_OUTPUT>" \
PHONE_NUMBER `base64 -w 0 ciphertext.bin`  \
projects/${GOOGLE_CLOUD_PROJECT}/locations/global/keyRings/dlp-keyring/cryptoKeys/dlp-key

출력은 수정이나 서러게이트 유형이 표시되지 않은 원본 문자열입니다.

My client's cell is 9006492568

데이터를 재식별하는 데 사용되는 함수는 데이터를 익명화하는 데 사용되는 함수와 유사합니다.

deid.js

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

다시 한번 말하지만 인수는 API에 대한 요청에 사용되며 이번에는 reidentifyContent 함수에 사용됩니다.

deid.js

  // Construct deidentification request
  const item = {value: string};
  const request = {
    parent: dlp.projectPath(callingProjectId),
    reidentifyConfig: {
      infoTypeTransformations: {
        transformations: [
          {
            primitiveTransformation: {
              cryptoReplaceFfxFpeConfig: {
                cryptoKey: {
                  kmsWrapped: {
                    wrappedKey: wrappedKey,
                    cryptoKeyName: keyName,
                  },
                },
                commonAlphabet: alphabet,
                surrogateInfoType: {
                  name: surrogateType,
                },
              },
            },
          },
        ],
      },
    },
    inspectConfig: {
      customInfoTypes: [
        {
          infoType: {
            name: surrogateType,
          },
          surrogateType: {},
        },
      ],
    },
    item: item,
  };

  try {
    // Run reidentification request
    const [response] = await dlp.reidentifyContent(request);

날짜 이동으로 날짜 익명화

특정 맥락에서 날짜는 난독화해야 할 수 있는 민감한 정보로 간주될 수 있습니다. 날짜 이동을 사용하면 기간의 순서와 기간을 유지하면서 날짜를 무작위 증분만큼 이동할 수 있습니다. 세트의 각 날짜는 항목에 고유한 시간만큼 이동합니다. 날짜 이동을 통한 식별 정보 삭제를 보여주기 위해 먼저 날짜 데이터가 포함된 샘플 CSV 파일을 살펴보세요.

resources/dates.csv

name,birth_date,register_date,credit_card
Ann,01/01/1980,07/21/1996,4532908762519852
James,03/06/1988,04/09/2001,4301261899725540
Dan,08/14/1945,11/15/2011,4620761856015295
Laura,11/03/1992,01/04/2017,4564981067258901

데이터에는 날짜 이동을 적용할 수 있는 두 필드(birth_dateregister_date)가 포함되어 있습니다. deid.js는 하한값과 상한값을 허용하여 날짜를 이동할 임의의 일수를 선택할 범위를 정의합니다.

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

datesShifted.csv이라는 파일이 생성되며, 날짜는 30~90일 사이의 일수만큼 무작위로 이동됩니다. 다음은 생성된 출력의 예입니다.

name,birth_date,register_date,credit_card
Ann,2/6/1980,7/21/1996,4532908762519852
James,5/18/1988,4/9/2001,4301261899725540
Dan,9/16/1945,11/15/2011,4620761856015295
Laura,12/16/1992,1/4/2017,4564981067258901

CSV 파일에서 이동할 날짜 열도 지정할 수 있습니다. birth_date 필드 register_date 필드는 변경되지 않습니다.

날짜 이동을 사용하여 식별 해제를 처리하는 함수를 살펴보겠습니다.

deid.js

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

이 함수는 FPE를 사용한 익명화와 마찬가지로 래핑된 키와 키 이름을 허용하여 날짜 이동을 재식별하기 위한 암호화 키를 제공할 수 있습니다. 제공된 인수는 dateShiftConfig 객체를 빌드합니다.

deid.js

  // Construct DateShiftConfig
  const dateShiftConfig = {
    lowerBoundDays: lowerBoundDays,
    upperBoundDays: upperBoundDays,
  };

  if (contextFieldId && keyName && wrappedKey) {
    dateShiftConfig.context = {name: contextFieldId};
    dateShiftConfig.cryptoKey = {
      kmsWrapped: {
        wrappedKey: wrappedKey,
        cryptoKeyName: keyName,
      },
    };
  } else if (contextFieldId || keyName || wrappedKey) {
    throw new Error(
      'You must set either ALL or NONE of {contextFieldId, keyName, wrappedKey}!'
    );
  }

  // Construct deidentification request
  const request = {
    parent: dlp.projectPath(callingProjectId),
    deidentifyConfig: {
      recordTransformations: {
        fieldTransformations: [
          {
            fields: dateFields,
            primitiveTransformation: {
              dateShiftConfig: dateShiftConfig,
            },
          },
        ],
      },
    },
    item: tableItem,
  };

5. 문자열 및 이미지 수정

민감한 정보를 난독화하는 또 다른 방법은 수정입니다. 수정은 일치하는 항목을 일치하는 것으로 식별된 정보 유형으로 대체합니다. redact.js은 수정사항을 보여줍니다.

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

출력은 샘플 신용카드 번호를 정보 유형 CREDIT_CARD_NUMBER로 바꿉니다.

Please refund the purchase on my credit card [CREDIT_CARD_NUMBER]

이는 민감한 정보를 숨기면서도 삭제되는 정보의 유형을 식별하려는 경우에 유용합니다. DLP API는 텍스트가 포함된 이미지에서도 이와 유사하게 정보를 수정할 수 있습니다. 예를 들어 샘플 이미지를 살펴보겠습니다.

resources/test.png

bf3719cfeb5676ff.png

위 이미지에서 전화번호와 이메일 주소를 수정하려면 다음 단계를 따르세요.

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

지정된 대로 요청된 정보가 가려진 redacted.png라는 새 이미지가 생성됩니다.

ce023dd95cccc40f.png

문자열에서 수정하는 데 사용되는 함수는 다음과 같습니다.

redact.js

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

다음은 deidentifyContent 함수에 제공될 요청입니다.

redact.js

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

마찬가지로 이미지 수정을 위한 함수는 다음과 같습니다.

redact.js

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

다음은 redactImage 함수에 제공될 요청입니다.

redact.js

// Construct image redaction request
  const request = {
    parent: dlp.projectPath(callingProjectId),
    byteItem: {
      type: fileTypeConstant,
      data: fileBytes,
    },
    inspectConfig: {
      minLikelihood: minLikelihood,
      infoTypes: infoTypes,
    },
    imageRedactionConfigs: imageRedactionConfigs,
  };

6. 삭제

DLP API를 사용하여 데이터에서 민감한 정보를 마스킹, 익명화, 수정하는 방법을 살펴봤습니다. 이제 생성한 리소스를 프로젝트에서 정리할 시간입니다.

프로젝트 삭제하기

GCP Console에서 Cloud Resource Manager 페이지로 이동합니다.

프로젝트 목록에서 작업 중인 프로젝트를 선택하고 삭제를 클릭합니다. 프로젝트 ID를 입력하라는 메시지가 표시됩니다. 프로젝트 ID를 입력하고 종료를 클릭합니다.

또는 gcloud를 사용하여 Cloud Shell에서 전체 프로젝트를 직접 삭제할 수 있습니다.

gcloud projects delete $GOOGLE_CLOUD_PROJECT

7. 축하합니다.

오호! 축하합니다. Cloud DLP는 강력한 민감한 정보 검사, 분류, 익명화 플랫폼에 대한 액세스를 제공하는 강력한 도구입니다.

학습한 내용

  • Cloud DLP API를 사용하여 여러 정보 유형에 대한 문자열과 파일을 검사하는 방법을 알아봤습니다.
  • DLP API가 마스크를 사용하여 정보 유형과 일치하는 데이터를 숨기도록 문자열을 익명화하는 방법을 알아봤습니다.
  • DLP API를 사용하여 암호화 키로 데이터를 익명화한 후 다시 식별했습니다.
  • DLP API를 사용하여 문자열과 이미지에서 데이터를 수정했습니다.