Redshift Python 加密/解密 UDF 错误 - 字符串包含无效或不受支持的 UTF8 代码点
Posted
技术标签:
【中文标题】Redshift Python 加密/解密 UDF 错误 - 字符串包含无效或不受支持的 UTF8 代码点【英文标题】:Redshift Python encrypt/decrypt UDF Error - String contains invalid or unsupported UTF8 codepoints 【发布时间】:2018-08-02 21:33:12 【问题描述】:我想在 Redshift 中创建以下加密和解密 UDF。
图书馆:
create library pyaes
language plpythonu
from 's3://aws_python/library/pyaes/pyaes.zip'
credentials 'aws-role'
region as 'aws-region';
加密:
CREATE OR REPLACE FUNCTION test.aes_encrypt(input varchar(max))
RETURNS varchar(max) AS
' if input is None:
return None
import pyaes
key = ''abcdefghijklopoo''
aes = pyaes.AESModeOfOperationCTR(key)
encrypted_msg = aes.encrypt(input)
return encrypted_msg
'
LANGUAGE plpythonu STABLE;
也尝试了以下选项:
encrypted_msg = aes.encrypt(input.encode("utf8"))
key = key.encode('utf-8')
解密:
CREATE OR REPLACE FUNCTION test.aes_decrypt(encrypted_msg varchar(max))
RETURNS varchar(max) AS
'
if encrypted_msg is None or len(str(encrypted_msg)) == 0:
return None
import pyaes
key = ''abcdefghijklopoo''
aes = pyaes.AESModeOfOperationCTR (key)
decrypted_msg = aes.decrypt(encrypted_msg).decode("utf8")
return decrypted_msg
'
LANGUAGE plpythonu STABLE;
选择 aes_encrypt('测试'); 选择 aes_decrypt('');
但它抛出以下错误:
错误:无效操作:字符串包含无效或不受支持的 UTF8 代码点。错误的 UTF8 十六进制序列:d5 fc(错误 4);
请指教。提前致谢。
【问题讨论】:
你为什么首先认为输入是 UTF-8? 嗨,当我创建函数并在 select 语句中使用它时,它会抛出错误:无效操作:字符串包含无效或不受支持的 UTF8 代码点。错误的 UTF8 十六进制序列:d5 fc(错误 4);因此,我尝试使用 utf-8 编码,但仍然抛出相同的错误。 请对此提出建议。不知道我在这段代码中哪里做错了。 @IgnacioVazquez-Abrams 你能建议一下吗? ***.com/questions/51735127/… 【参考方案1】:我在一个可以查看输出的笔记本中完成了这项工作。基本上,当 AES 函数发生时会发生错误,您无法看到其输出,并且它会将错误类型传递回 Redshift,因为 aes 作为字节返回。
请注意:这是为了对数据列进行加密混淆,而不是服务器端加密。如果安全性很重要,请加密您的整个数据库。如果您打算使用它来保护您的客户数据,请不要,请加密盐和散列所有内容等。这是您的免责声明。
这需要转换为 redshift 可以处理的东西,比如十六进制,所以使用 'binascii.hexlify(cipher_txt)' 以可打印的方式取回值。
CREATE OR REPLACE FUNCTION aes_encrypt(input VARCHAR(20000))
RETURNS VARCHAR STABLE AS $$
import pyaes
import binascii
if input is None:
return None
key = 'abcdefghijklnosp'
aes=pyaes.AESModeOfOperationCTR(key)
cipher_txt=aes.encrypt(input)
cipher_txt2=binascii.hexlify(cipher_txt)
return str(cipher_txt2.decode('utf-8'))
$$ LANGUAGE plpythonu ;
注意返回时解码是多余的,密文被分成几行来说明。我相信你可以把它们放回一行。喜欢 cipher_txt=binascii.hexlify(aes.encrypt(input))
解密:
CREATE OR REPLACE FUNCTION aes_decrypt(encrypted_msg varchar(max))
RETURNS VARCHAR STABLE AS $$
import pyaes
import binascii
if encrypted_msg is None or len(str(encrypted_msg)) == 0:
return None
key = 'abcdefghijklnosp'
aes = pyaes.AESModeOfOperationCTR(key)
encrypted_msg2=binascii.unhexlify(encrypted_msg)
decrypted_msg2 = aes.decrypt(encrypted_msg2)
return str(decrypted_msg2.decode('utf-8'))
$$ LANGUAGE plpythonu ;
另外 - 旁注 - 你不需要指定返回 varchar 的长度,除非你需要出于其他原因(联合或类似的) - 因为使一切都最大化是浪费空间。
【讨论】:
以上是关于Redshift Python 加密/解密 UDF 错误 - 字符串包含无效或不受支持的 UTF8 代码点的主要内容,如果未能解决你的问题,请参考以下文章
使用Java继承UDF类或GenericUDF类给Hive3.1.2编写UDF实现编码解码加密解密并运行在USDP大数据集群
使用Java继承UDF类或GenericUDF类给Hive3.1.2编写UDF实现编码解码加密解密并运行在USDP大数据集群
您可以从 Redshift 中的 python UDF 返回多个值吗?