Parquet 模块加密可以使用任意“密钥管理服务”(KMS) 服务器。 必须向 Analytics Engine powered by Apache Spark 实例提供能够与所选 KMS 服务器通信的定制 KMS 客户机类。 此类需要实现 KmsClient 接口(Parquet 模块加密 API 的一部分)。 Analytics Engine powered by Apache Spark 包含 VaultClient KmsClient,后者可在您将 Hashicorp Vault 用作主密钥的 KMS 服务器时现成使用。 如果您使用或计划使用不同的 KMS 系统,可以开发一个定制 KmsClient 类(以 VaultClient 代码为示例)。
定制 KmsClient 类
Parquet 模块加密提供了称为 org.apache.parquet.crypto.keytools.KmsClient
的简单接口,其中包含您必须实现的以下两个主函数:
// Wraps a key - encrypts it with the master key, encodes the result and
// potentially adds KMS-specific metadata.
public String wrapKey(byte[] keyBytes, String masterKeyIdentifier)
// Decrypts (unwraps) a key with the master key.
public byte[] unwrapKey(String wrappedKey, String masterKeyIdentifier)
此外,该接口还提供了用于传递 KMS 参数和其他配置的以下初始化函数:
public void initialize(Configuration configuration, String kmsInstanceID, String kmsInstanceURL, String accessToken)
请参阅 KmsClient 实现示例以了解如何实现 KmsClient。
开发定制 KmsClient 类后,将其添加到提供给 Analytics Engine powered by Apache Spark 的 jar,并传递其在 Spark Hadoop 配置中的全名,例如:
sc.hadoopConfiguration.set("parquet.ecnryption.kms.client.class", "full.name.of.YourKmsClient"
由 Hashicorp Vault 管理密钥
如果决定将 Hashicorp Vault 用作 KMS 服务器,可以使用预先打包的 VaultClient:
sc.hadoopConfiguration.set("parquet.ecnryption.kms.client.class", "com.ibm.parquet.key.management.VaultClient")
创建主密钥
请参阅 Hashicorp Vault 文档以了解有关 Vault 上的操作的具体信息。 请参阅:
- 在缺省路径启用 Transit Engine,或通过提供定制路径来启用。
- 创建指定的加密密钥。
- 配置用于允许用户或机器访问这些指定密钥的访问策略。
写入已加密的数据
传递以下参数:
将
"parquet.encryption.kms.client.class"
设置为"com.ibm.parquet.key.management.VaultClient"
:sc.hadoopConfiguration.set("parquet.ecnryption.kms.client.class", "com.ibm.parquet.key.management.VaultClient")
可选: 设置传输引擎的定制路径
"parquet.encryption.kms.instance.id"
:sc.hadoopConfiguration.set("parquet.encryption.kms.instance.id" , "north/transit1")
将
"parquet.encryption.kms.instance.url"
设置为保险库文件实例的 URL:sc.hadoopConfiguration.set("parquet.encryption.kms.instance.url" , "https://<hostname>:8200")
将
"parquet.encryption.key.access.token"
设置为连接了访问策略的有效访问令牌,这将提供对保险库文件实例中所需密钥的访问权:sc.hadoopConfiguration.set("parquet.encryption.key.access.token" , "<token string>")
如果令牌位于本地文件中,请装入该令牌:
val token = scala.io.Source.fromFile("<token file>").mkStringsc.hadoopConfiguration.set("parquet.encryption.key.access.token" , token)
指定需要加密哪些列,以及使用哪些主密钥。 还必须指定 footer 密钥。 例如:
val k1 = "key1" val k2 = "key2" val k3 = "key3" dataFrame.write .option("parquet.encryption.footer.key" , k1) .option("parquet.encryption.column.keys" , k2+":SSN,Address;"+k3+":CreditCard") .parquet("<path to encrypted files>")
注: 如果未设置
"parquet.encryption.column.keys"
或"parquet.encryption.footer.key"
参数,那么将抛出异常。
读取已加密的数据
必需的元数据(包括 Hashicorp Vault 实例的标识和 URL)存储在已加密 Parquet 文件中。
要读取已加密的元数据:
将 KMS 客户机设置为 Vault 客户机实现:
sc.hadoopConfiguration.set("parquet.ecnryption.kms.client.class", "com.ibm.parquet.key.management.VaultClient")
提供附加有策略的访问令牌,用于授予对相关密钥的访问权:
sc.hadoopConfiguration.set("parquet.encryption.key.access.token" , "<token string>")
调用常规 Parquet 读取命令,例如:
val dataFrame = spark.read.parquet("<path to encrypted files>")
密钥轮换
如果需要密钥轮换,有权访问 KMS 密钥轮换操作的管理员必须使用 Hashicorp Vault 文档中描述的过程在 Hashicorp Vault 中轮换主密钥。 在此之后,管理员可以通过调用以下代码来触发 Parquet 密钥轮换:
public static void KeyToolkit.rotateMasterKeys(String folderPath, Configuration hadoopConfig)
要启用 Parquet 密钥轮换,必须设置以下 Hadoop 配置属性:
- 必须设置参数
"parquet.encryption.key.access.token"
和"parquet.encryption.kms.instance.url"
,并且 (可选)"parquet.encryption.kms.instance.id"
- 参数
"parquet.encryption.key.material.store.internally"
必须设置为"false"
。 - 参数
"parquet.encryption.kms.client.class"
必须设置为"com.ibm.parquet.key.management.VaultClient"
例如:
sc.hadoopConfiguration.set("parquet.encryption.kms.instance.url" , "https://<hostname>:8200")sc.hadoopConfiguration.set("parquet.encryption.key.access.token" , "<token string>")
sc.hadoopConfiguration.set("parquet.encryption.kms.client.class","com.ibm.parquet.key.management.VaultClient")
sc.hadoopConfiguration.set("parquet.encryption.key.material.store.internally", "false")
KeyToolkit.rotateMasterKeys("<path to encrypted files>", sc.hadoopConfiguration)
父主题: Parquet 加密