파케트 모듈식 암호화
데이터가 열 기반 형식으로 저장된 경우, Parquet 파일을 작성할 때 Parquet 모듈형 암호화를 사용하여 민감한 열을 암호화하고, 암호화된 파일을 읽을 때 해당 열을 복호화할 수 있습니다. 열 단위로 데이터를 암호화하면, 어떤 열을 암호화할지, 그리고 열에 대한 액세스를 어떻게 제어할지 직접 결정할 수 있습니다.
파케트 모듈형 암호화는 개인정보 보호는 물론, 저장된 데이터의 무결성도 보호합니다. 파일 내용의 무단 변경이 감지되면 리더 측에서 예외가 발생합니다.
주요 기능은 다음과 같습니다:
Parquet 모듈식 암호화 및 복호화는 Spark 클러스터에서 수행됩니다. 따라서 민감한 데이터와 암호화 키는 스토리지에서 확인할 수 없습니다.
인코딩, 압축, 열 기반 투영 및 술어 푸시다운과 같은 표준 Parquet 기능은 Parquet 모듈형 암호화 형식을 사용하는 파일에서도 평소와 같이 계속 작동합니다.
Parquet 사양에 정의된 두 가지 암호화 알고리즘 중 하나를 선택할 수 있습니다. 두 알고리즘 모두 열 암호화를 지원하지만:
- 기본 알고리즘은 Parquet 파일 내의 데이터 및 메타데이터
AES-GCM부분에 대한 변조로부터 완벽한 보호 기능을 제공합니다. - 이 대체 알고리즘은 Parquet 파일의
AES-GCM-CTR부분적 무결성 보호를 지원합니다. 변조로부터 보호되는 것은 메타데이터 부분뿐이며, 데이터 부분은 보호되지 않습니다. 이 알고리즘의 장점은 기존AES-GCM알고리즘에 비해 처리량 오버헤드가 적다는 점입니다.
- 기본 알고리즘은 Parquet 파일 내의 데이터 및 메타데이터
암호화할 열을 선택할 수 있습니다. 다른 열은 암호화되지 않으므로 처리량 오버헤드가 줄어듭니다.
서로 다른 열은 서로 다른 키로 암호화할 수 있습니다.
기본적으로 Parquet의 주요 메타데이터 모듈(파일 푸터)은 파일 스키마와 민감한 열 목록을 숨기기 위해 암호화됩니다. 그러나 레거시 리더(예: 아직 Parquet 모듈형 암호화를 지원하지 않는 다른 Spark 배포판 등)가 암호화된 파일 내의 암호화되지 않은 열을 읽을 수 있도록 하기 위해, 파일 푸터를 암호화하지 않도록 선택할 수도 있습니다.
암호화 키는 다음 두 가지 방법 중 하나로 관리할 수 있습니다:
- 앱에서 바로. ‘애플리케이션별 키 관리’를 참조하십시오.
- Spark 서비스에서 사용하는 암호화 키를 생성, 저장 및 파기하는 키 관리 시스템(KMS)을 통해. 이 키들은 KMS 서버를 절대 벗어나지 않으므로, Spark 서비스를 포함한 다른 구성 요소에서는 확인할 수 없습니다. KMS를 통한 키 관리를 참조하십시오.
참고: 귀하의 애플리케이션 또는 KMS는 마스터 암호화 키만 관리해야 합니다.각 민감한 열에 대해, 암호화에 사용할 기본 키를 지정해야 합니다. 또한, 각 암호화된 파일(데이터 프레임)의 바닥글에는 마스터 키를 지정해야 합니다. 기본적으로 푸터 키가 푸터 암호화에 사용됩니다. 그러나 일반 텍스트 푸터 모드를 선택하면 푸터는 암호화되지 않으며, 해당 키는 푸터의 무결성 검증에만 사용됩니다.
암호화 매개변수는 표준 Spark ` Hadoop ` 구성을 통해 전달할 수 있습니다. 예를 들어, 애플리케이션의 ` SparkContext: ` 파일 내 ` Hadoop ` 구성에서 해당 값을 설정하는 방식이 있습니다
sc.hadoopConfiguration.set("<parameter name>" , "<parameter value>")또는 쓰기 옵션을 통해 매개변수 값을 전달할 수도 있습니다:
<data frame name>.write .option("<parameter name>" , "<parameter value>") .parquet("<write path>")
필수 매개변수
암호화된 데이터를 기록하려면 다음 매개변수가 필요합니다:
암호화할 열 목록과 마스터 암호화 키:
parameter name: "encryption.column.keys" parameter value: "<master key ID>:<column>,<column>;<master key ID>:<column>,.."푸터 키:
parameter name: "encryption.footer.key" parameter value: "<master key ID>"예를 들어,
dataFrame.write .option("encryption.footer.key" , "k1") .option("encryption.column.keys" , "k2:SSN,Address;k3:CreditCard") .parquet("<path to encrypted files>")중요:encryption.column.keys매개변수와encryption.footer.key매개변수를 모두 설정하지 않으면 파일이 암호화되지 않습니다. 이 매개변수 중 하나만 설정된 경우, 암호화된 파일에 대해 이 매개변수들이 필수 사항이므로 예외가 발생합니다.
선택적 매개변수
암호화된 데이터를 기록할 때 다음의 선택적 매개변수를 사용할 수 있습니다:
암호화 알고리즘
AES-GCM-CTR기본적으로 Parquet 모듈형 암호화는 Parquet 파일 내의 데이터 및 메타데이터가 변조되는 것을 완벽하게 방지하는 알고리즘을
AES-GCM사용합니다. 그러나 Spark 2.3.0 는 Java 8 기반으로 실행되는데, Java 8은 CPU 하드웨어 수준의 AES 가속을 지원하지 않기 때문에(이 기능은 Java 9에서야 추가됨), 특정 상황에서는 데이터 무결성 검증에 따른 오버헤드가 워크로드 처리량에 영향을 미칠 수 있습니다.이를 보완하기 위해 데이터 무결성 검증 기능을 비활성화하고, 데이터 부분의 무결성은 검증하지 않고 메타데이터 부분의 무결성만 검증하며 기존
AES-GCM알고리즘에 비해 처리량 오버헤드가 더 낮은 대체 알고리즘을 사용하여 암호화된 파일을AES-GCM-CTR기록할 수 있습니다.parameter name: "encryption.algorithm" parameter value: "AES_GCM_CTR_V1"구형 리더기를 위한 일반 텍스트 바닥글 모드
기본적으로 Parquet의 주요 메타데이터 모듈(파일 푸터)은 파일 스키마와 민감한 열 목록을 숨기기 위해 암호화됩니다. 하지만, (아직 Parquet 모듈형 암호화를 지원하지 않는) 다른 Spark 및 Parquet 리더가 암호화된 파일 내의 암호화되지 않은 열을 읽을 수 있도록 하기 위해 파일 푸터를 암호화하지 않기로 결정할 수도 있습니다. 푸터 암호화를 해제하려면 다음 매개변수를 설정하십시오:
parameter name: "encryption.plaintext.footer" parameter value: "true"중요:일반 텍스트 바닥글 모드에서도
encryption.footer.key매개변수를 지정해야 합니다. 푸터는 암호화되어 있지 않지만, 키를 사용하여 푸터 내용에 서명을 하므로, 새로운 독자들도 그 무결성을 확인할 수 있습니다. 기존 버전 사용자들은 바닥글 서명이 추가되어도 영향을 받지 않습니다.
사용 예제
Python 의 다음 샘플 코드 스니펫은 데이터 프레임을 작성하고 암호화된 parquet 파일에 기록하며 암호화된 parquet 파일에서 읽는 방법을 보여줍니다.
Python : 암호화된 데이터 쓰기:
from pyspark.sql import Row squaresDF = spark.createDataFrame( sc.parallelize(range(1, 6)) .map(lambda i: Row(int_column=i, square_int_column=i ** 2))) sc._jsc.hadoopConfiguration().set("encryption.key.list", "key1: AAECAwQFBgcICQoLDA0ODw==, key2: AAECAAECAAECAAECAAECAA==") sc._jsc.hadoopConfiguration().set("encryption.column.keys", "key1:square_int_column") sc._jsc.hadoopConfiguration().set("encryption.footer.key", "key2") encryptedParquetPath = "squares.parquet.encrypted" squaresDF.write.parquet(encryptedParquetPath)Python : 암호화된 데이터 읽기:
sc._jsc.hadoopConfiguration().set("encryption.key.list", "key1: AAECAwQFBgcICQoLDA0ODw==, key2: AAECAAECAAECAAECAAECAA==") encryptedParquetPath = "squares.parquet.encrypted" parquetFile = spark.read.parquet(encryptedParquetPath) parquetFile.show()
Parquet 모듈형 암호화를 사용하는 Spark 작업 제출 예시
다음 예제는 Parquet 모듈형 암호화를 사용하는 Spark 작업을 Spark 인스턴스에 제출하는 방법을 보여줍니다. 이 예에서는 기본 Spark 템플리트를 사용하여 InMemoryKMS.py파일에서 Python spark 작업을 제출합니다. 이 예시는 해당 파일이 루트 디렉터리에 있는 저장 zen::kms-volume 볼륨에 존재한다고 가정합니다.
{
"application_details": {
"application": "/kms-app/kms.py",
"conf": {
"ae.spark.executor.count": 2,
"spark.driver.memory": "4G",
"spark.executor.memory": "4G"
}
},
"volumes": [
{
"name": "zen::kms-volume",
"mount_path": "/kms-app"
}
]
}
Python 작업 파일 InMemoryKMS.py 의 내용은 다음과 같습니다.
from pyspark.sql import SparkSession
from pyspark import SparkContext
from pyspark.sql import Row
if __name__ == "__main__":
spark = SparkSession \
.builder \
.appName("InMemoryKMS") \
.getOrCreate()
sc = spark.sparkContext
##KMS operation
print("Setup InMemoryKMS")
hconf = sc._jsc.hadoopConfiguration()
encryptedParquetFullName = "testparquet.encrypted"
print("Write Encrypted Parquet file")
hconf.set("encryption.key.list", "key1: AAECAwQFBgcICQoLDA0ODw==, key2: AAECAAECAAECAAECAAECAA==")
btDF = spark.createDataFrame(sc.parallelize(range(1, 6)).map(lambda i: Row(ssn=i, value=i ** 2)))
btDF.write.mode("overwrite").option("encryption.column.keys", "key1:ssn").option("encryption.footer.key", "key2").parquet(encryptedParquetFullName)
print("Read Encrypted Parquet file")
encrDataDF = spark.read.parquet(encryptedParquetFullName)
encrDataDF.createOrReplaceTempView("bloodtests")
queryResult = spark.sql("SELECT ssn, value FROM bloodtests")
queryResult.show(10)
sc.stop()
spark.stop()
암호화 키 처리의 내부 구조
Parquet 파일을 작성할 때, 각 암호화 열과 푸터에 대해 무작위 데이터 암호화 키(DEK)가 생성됩니다. 이 키들은 Parquet 파일 내의 데이터 및 메타데이터 모듈을 암호화하는 데 사용됩니다.
그런 다음 데이터 암호화 키는 각 마스터 키에 대해 Spark/Parquet 내부에서 생성된 키 암호화 키(KEK)를 사용하여 암호화됩니다. 암호화 키는 로컬에서 마스터 암호화 키(MEK)로 암호화됩니다.
암호화된 데이터의 암호화 키와 키 암호화 키는 마스터 키 식별자와 함께 Parquet 파일의 메타데이터에 저장됩니다. 각 암호화 키는 고유한 식별자(로컬에서 생성된 안전한 16바이트 임의 값)를 가지며, 이 식별자 또한 파일 메타데이터에 저장됩니다.
Parquet 파일을 읽을 때, 마스터 암호화 키(MEK)의 식별자와 해당 식별자가 포함된 암호화된 키 암호화 키(KEK), 그리고 암호화된 데이터 암호화 키(DEK)가 파일 메타데이터에서 추출됩니다.
암호화 키는 로컬에서 마스터 암호화 키를 사용하여 복호화됩니다. 그런 다음 키 암호화 키(KEK)를 사용하여 데이터 암호화 키(DEK)를 로컬에서 복호화합니다.