如何使用AWS KMS加密Pandas/Spark数据帧中的列

如何使用AWS KMS加密Pandas/Spark数据帧中的列,pandas,encryption,pyspark,aws-kms,Pandas,Encryption,Pyspark,Aws Kms,我想加密Pandas(或py/spark)数据帧的一列中的值,例如,要获取以下数据帧中的列mobno,请对其进行加密,并将结果放入加密的\u值列中: 我想使用AWS KMS加密密钥。我的问题是:最优雅的方式是什么 我正在考虑使用UDF,它将调用boto3的KMS客户端。比如: @udf def加密(明文): 响应=kms\u client.encrypt( KeyId=aws\U kms\U key\U id, 纯文本 ) ciphertext=响应['CiphertextBlob'] 返回密

我想加密Pandas(或py/spark)数据帧的一列中的值,例如,要获取以下数据帧中的列
mobno
,请对其进行加密,并将结果放入
加密的\u值
列中:

我想使用AWS KMS加密密钥。我的问题是:最优雅的方式是什么

我正在考虑使用UDF,它将调用boto3的KMS客户端。比如:

@udf
def加密(明文):
响应=kms\u client.encrypt(
KeyId=aws\U kms\U key\U id,
纯文本
)
ciphertext=响应['CiphertextBlob']
返回密文
然后在整个列上应用这个udf

但我不太相信这是正确的方法。这源于我是一名加密新手这一事实——首先,我甚至不知道这个
kms\u client\u encrypt
函数是用于加密值(来自列)还是用于操作密钥。也许更好的方法是获取密钥,然后使用一些python加密库(例如
hashlib


我想澄清一下加密过程,并建议列加密的最佳方法。

为了避免在UDF中多次调用KMS服务,请使用AWS Secrets Manager检索加密密钥,并使用
pycrypto
加密列。以下工作:

from pyspark.sql.functions import udf, col
from Crypto.Cipher import AES

region_name = "eu-west-1"
session = boto3.session.Session()
client = session.client(service_name='secretsmanager', region_name=region_name)
get_secret_value_response = client.get_secret_value(SecretId=secret_name)
secret_key = json.loads(get_secret_value_response['SecretString'])
clear_text_column = 'mobo'

def encrypt(key, text):
    obj = AES.new(key, AES.MODE_CFB, 'This is an IV456')
    return obj.encrypt(text)

def udf_encrypt(key):
    return udf(lambda text: encrypt(key, text))

df.withColumn("encrypted", udf_encrypt(secret_key)(col(clear_text_column))).show()
或者,使用@Vektor88(PySpark 3语法)建议的更高效的UDF:


如果使用的键始终相同,也可以实现pandas UDF,而不是常规UDF,以一次性获取键并在整个列上应用该函数,转换为pandas系列。好主意@Vektor88。我添加了一个熊猫UDF替代方案。
from functools import partial

encrypt_with_key = partial(encrypt, secret_key)

@pandas_udf(BinaryType())
def pandas_udf_encrypt(clear_strings: pd.Series) -> pd.Series:
    return clear_strings.apply(encrypt_with_key)

df.withColumn('encrypted', pandas_udf_encrypt(clear_text_column)).show()