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

프로젝트 코드가 다운로드되면 샘플 디렉터리로 변경하고 필요한 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. 문자열 및 파일 검사

이전 단계에서 다운로드한 프로젝트의 샘플 디렉터리에는 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는 Google에서 만든 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

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

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를 사용하여 문자열과 이미지의 데이터를 수정했습니다.