使用Oracle DBMS_CRYPTO.PKENCRYPT进行RSA公钥加密时遇ORA-28817错误
使用DBMS_CRYPTO.PKENCRYPT进行RSA加密时遇ORA-28817错误的排查与解决
问题场景
尝试创建存储过程,通过DBMS_CRYPTO.PKENCRYPT函数用客户端提供的RSA公钥加密输入文本,示例代码如下:
DECLARE ip_str VARCHAR (200) := 'Secret Message'; pubkey VARCHAR (2000) := 'samplekey'; enc_raw RAW (2000); kType PLS_INTEGER := DBMS_CRYPTO.KEY_TYPE_RSA; eType PLS_INTEGER := DBMS_CRYPTO.PKENCRYPT_RSA_PKCS1_OAEP; BEGIN enc_raw := DBMS_CRYPTO.PKENCRYPT ( src => UTL_I18N.STRING_TO_RAW(ip_str,'AL32UTF8'), pub_key => UTL_I18N.STRING_TO_RAW(pubkey, 'AL32UTF8'), pubkey_alg => kType, enc_alg => eType ); dbms_output.put_line('Encrypted : ' || utl_raw.cast_to_varchar2(enc_raw )); end; /
运行时抛出错误:
ORA-28817: PL/SQL function returned an error. ORA-06512: at "SYS.DBMS_CRYPTO_FFI", line 258 ORA-06512: at "SYS.DBMS_CRYPTO", line 143 ORA-06512: at line 10 28817. 00000 - "PL/SQL function returned an error." *Cause: A PL/SQL function returned an error unexpectedly. *Action: This is an internal error. Enable tracing to find more information. Contact Oracle customer support if needed. *Document: NO
错误原因与修正方法
- 公钥格式不兼容:
DBMS_CRYPTO.PKENCRYPT要求RSA公钥必须是DER编码的RAW类型,不能直接传入普通字符串(如示例中的samplekey)。如果客户端提供的是PEM格式公钥(带-----BEGIN PUBLIC KEY-----/-----END PUBLIC KEY-----头尾),需先处理转换:-- 示例:将PEM公钥转换为符合要求的RAW格式 DECLARE l_pem_pubkey VARCHAR2(4000) := '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----'; l_clean_pubkey VARCHAR2(4000); l_raw_pubkey RAW(2000); BEGIN -- 去除PEM头尾标记 l_clean_pubkey := REPLACE(REPLACE(l_pem_pubkey, '-----BEGIN PUBLIC KEY-----', ''), '-----END PUBLIC KEY-----', ''); -- 移除换行符 l_clean_pubkey := REPLACE(l_clean_pubkey, CHR(10), ''); -- Base64解码为RAW l_raw_pubkey := UTL_ENCODE.BASE64_DECODE(UTL_I18N.STRING_TO_RAW(l_clean_pubkey, 'AL32UTF8')); END; - 加密内容长度超限:RSA PKCS1_OAEP加密有长度限制,最大明文长度为「密钥字节数 - 42」(例如2048位密钥对应256字节,最大明文长度为214字节)。若输入文本超过该长度,需缩短内容或改用「对称加密明文+RSA加密对称密钥」的混合方案。
- 变量长度需匹配:加密后的RAW长度等于密钥字节数(2048位密钥对应256字节),需确保
enc_raw的RAW长度足够容纳结果(示例中RAW(2000)满足需求,但4096位密钥需调整为RAW(512)以上)。 - 权限验证:确认当前用户拥有
DBMS_CRYPTO包的执行权限,若没有需执行授权:GRANT EXECUTE ON SYS.DBMS_CRYPTO TO your_username;
内容的提问来源于stack exchange,提问作者Akash ATG
相关产品推荐
相关产品推荐

