이 페이지에서는 Cloud SQL에서 클라이언트 측 암호화를 구현하는 방법을 설명합니다.
개요
클라이언트 측 암호화는 Cloud SQL에 데이터를 기록하기 전에 데이터를 암호화하는 작업입니다. 애플리케이션만 복호화할 수 있는 방식으로 Cloud SQL 데이터를 암호화할 수 있습니다.
클라이언트 측 암호화를 사용 설정하려면 다음 옵션을 사용하세요.
- Cloud Key Management Service(Cloud KMS)에 저장된 암호화 키를 사용합니다.
- 애플리케이션에 로컬로 저장된 암호화 키를 사용합니다.
이 주제에서는 가장 원활한 키 관리 옵션을 제공하는 첫 번째 옵션을 사용하는 방법을 설명합니다. Google에서는 Cloud KMS에 암호화 키를 만들고 Google의 오픈소스 암호화 라이브러리인 Tink를 사용하여 봉투 암호화를 구현합니다.
클라이언트 측 암호화가 필요한 이유는 무엇인가요?
열 수준 1에서 Cloud SQL 데이터를 보호하려면 클라이언트측 암호화가 필요합니다. 이름과 신용카드 번호를 포함하는 테이블이 있다고 가정해 보겠습니다. 사용자에게 이 테이블에 대한 액세스 권한을 부여하려고 하지만 사용자가 신용카드 번호를 보는 것은 원하지 않을 수 있습니다. 클라이언트 측 암호화를 사용하여 번호를 암호화할 수 있습니다. 사용자가 Cloud KMS의 암호화 키에 대한 액세스 권한을 부여받지 않는 한 신용카드 정보를 읽을 수 없습니다.
Cloud KMS를 사용하여 키 만들기
Cloud KMS를 사용하면 Google Cloud Platform에서 키를 만들고 관리할 수 있습니다.
Cloud KMS는 다양한 키 유형을 지원합니다. 클라이언트 측 암호화의 경우 대칭 키를 만들어야 합니다.
애플리케이션에 Cloud KMS의 키에 대한 액세스 권한을 부여하려면 애플리케이션에서 사용하는 서비스 계정에 cloudkms.cryptoKeyEncrypterDecrypter
역할을 부여해야 합니다. gcloud에서는 다음 명령어를 사용하여 이 작업을 수행합니다.
gcloud kms keys add-iam-policy-binding key \ --keyring=key-ring \ --location=location \ --member=serviceAccount:service-account-name@example.domain.com \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
KMS 키를 사용하여 직접 데이터를 암호화할 수 있지만 여기에서는 봉투 암호화라는 더 유연한 솔루션을 사용합니다. 그러면 Cloud Key Management Service API가 지원할 수 있는 최대 메시지 크기인 64KB보다 긴 메시지를 암호화할 수 있습니다.
Cloud KMS 봉투 암호화
봉투 암호화에서 KMS 키는 키 암호화 키(KEK) 역할을 합니다. 즉, 실제 데이터를 암호화하는 데 사용되는 데이터 암호화 키(DEK)를 암호화하는 데 사용됩니다.
Cloud KMS에서 KEK를 만든 후 각 메시지를 암호화하려면 다음을 수행해야 합니다.
- 로컬에서 데이터 암호화 키(DEK)를 생성합니다.
- 이 DEK를 로컬에서 사용하여 메시지를 암호화합니다.
- Cloud KMS를 호출하여 KEK로 DEK를 암호화(래핑)합니다.
- 암호화된 데이터와 래핑된 DEK를 저장합니다.
이 주제에서는 봉투 암호화를 처음부터 구현하는 대신 Tink를 사용합니다.
Tink
Tink는 고수준 암호화 API를 제공하는 다국어 교차 플랫폼 라이브러리입니다. Tink의 봉투 암호화로 데이터를 암호화하려면 Cloud KMS의 KEK를 가리키는 키 URI 및 Tink가 KEK를 사용할 수 있도록 하는 사용자 인증 정보를 Tink에 제공해야 합니다. Tink는 DEK를 생성하고, 데이터를 암호화하고, DEK를 래핑하고, 암호화된 데이터와 래핑된 DEK가 있는 단일 암호문을 반환합니다.
Tink는 AEAD API를 사용하여 C++, 자바, Go, Python에서 봉투 암호화를 지원합니다.
public interface Aead{
byte[] encrypt(final byte[] plaintext, final byte[] associatedData)
throws…
byte[] decrypt(final byte[] ciphertext, final byte[] associatedData)
throws…
}
일반 메시지/암호문 인수 외에도 암호화 및 복호화 메서드는 추가 관련 데이터를 지원합니다. 이 인수는 암호문을 데이터 조각과 연결하는 데 사용할 수 있습니다. 예를 들어 user-id
필드와 encrypted-medical-history
필드가 있는 데이터베이스가 있다고 가정해 보겠습니다. 이 경우 의료 기록을 암호화할 때 user-id
필드를 연결된 데이터로 사용해야 할 수 있습니다. 이렇게 하면 공격자가 한 사용자의 의료 기록을 다른 사용자로 이동할 수 없습니다. 또한 쿼리를 실행할 때 올바른 데이터 행이 있는지 확인하는 데도 사용됩니다.
샘플
이 섹션에서는 클라이언트 측 암호화를 사용하는 유권자 정보 데이터베이스의 샘플 코드를 살펴봅니다. 샘플 코드는 다음을 수행하는 방법을 보여줍니다.
- 데이터베이스 테이블 및 연결 풀 만들기
- 봉투 암호화를 위한 Tink 설정
- Cloud KMS의 KEK로 Tink의 봉투 암호화를 사용하여 데이터 암호화 및 복호화
시작하기 전에
다음 안내에 따라 Cloud SQL 인스턴스를 만듭니다. 생성한 연결 문자열, 데이터베이스 사용자, 데이터베이스 비밀번호를 기록해 둡니다.
안내에 따라 애플리케이션용 데이터베이스를 만듭니다. 데이터베이스 이름을 기록해 둡니다.
안내에 따라 애플리케이션의 KMS 키를 만듭니다. 생성된 키의 리소스 이름을 복사합니다.
안내에 따라 'Cloud SQL 클라이언트' 권한으로 서비스 계정을 만듭니다.
안내에 따라 서비스 계정에 키에 대한 'Cloud KMS CryptoKey 암호화/복호화' 권한을 추가합니다.