【问题标题】:Oracle encrypt/decrypt a clobOracle 加密/解密 clob
【发布时间】:2021-09-10 18:18:05
【问题描述】:

我基于 clob 构建了一个 sha512 哈希 KEY,因此我可以轻松检查 clob 是否已经存在。

它基于一个 INSERT 触发器,该触发器旨在调用将创建哈希键的函数。

我可以成功地创建我的表、函数和触发器以及 INSERT 行。

我的下一步是存储在 INSERT 期间加密的 CLOB,并在 SELECT 期间为拥有特权的人在 SELECT 期间解密 CLOB。

我在互联网上发现了一些可以加密的代码(见下文),但我遇到的问题是能够解密 clob。我怀疑这应该是可能的,但我找不到任何如何完成此任务的示例。

其次,我在代码中看到了一个密钥,这意味着任何拥有 DBA 权限的人都可以查看源代码并看到密钥,这是我不想要的。

避免这种情况的最佳方法是将代码转换为包并加密包,使密钥和加密方法未知?

我怀疑在这个项目之后,一些敏感的字符串和 BLOB 将不得不经历同样的事情,所以我希望有一个非常灵活的解决方案来涵盖这些情况,或者做一些改动很小的事情,因为我不想重新发明轮子。

最后,如果有比我找到的更好的加密方法,请告诉我。因为我还没有绑定任何方法。

我们将不胜感激任何帮助和专业知识。提前感谢所有回答的人。我正在为任何想要模拟我的环境的人测试 livesql。

下面是一个简单的测试案例。为冗长的文章道歉。

CREATE table t(
seq_num integer  GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
c CLOB,
hash VARCHAR2(1000)
);

  
 CREATE or REPLACE FUNCTION HASH_SHA512 (
    psINPUT IN VARCHAR2
    ) RETURN VARCHAR2 AS
    rHash RAW (512);
    BEGIN
    rHash := DBMS_CRYPTO.HASH (TO_CLOB (psINPUT), 
dbms_crypto.HASH_SH512);
    RETURN (LOWER (RAWTOHEX (rHash)));
    END HASH_SHA512;
   

create or replace
    trigger trg
    before insert on  t
   for each row
    begin
    :new.hash := HASH_SHA512(:new.c);
    end;
  

 insert into t (c) values (
      rpad('z',32000,'z')
  );

SELECT DBMS_LOB.getLength(c) from t;

select hash from t;


-- looking for a decrypt function for this code.


create or replace function clob_encrypt(ac_input IN CLOB) return blob is 
  lb_variable BLOB; 
  inverse_type PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_DES + 
                                 DBMS_CRYPTO.CHAIN_CBC + 
                                 DBMS_CRYPTO.PAD_PKCS5; 
  inverse_key RAW(32) := UTL_RAW.cast_to_raw( '1220248819'); 
begin 
 
 dbms_lob.createtemporary(lb_variable, true);
 
 DBMS_CRYPTO.ENCRYPT( 
                 dst => lb_variable, 
                 src => ac_input, 
                 typ => inverse_type,--dbms_crypto.des_cbc_pkcs5, 
                 key => inverse_key 
                 ); 

   return lb_variable; 
end clob_encrypt;

select clob_encrypt('test') from dual;

CLOB_ENCRYPT('TEST')   
DEBD62BE84FC22A

【问题讨论】:

  • 如果DBMS_CRYPTOENCRYPT 功能,那么它应该(合理地)有DECRYPT 功能。
  • 使用加密和解密并将所有内容包含在一个包中。然后使用wrap加密代码。

标签: sql oracle encryption clob


【解决方案1】:

Oracle 对这个问题的内置解决方案不是加密,而是使用 Database Vault 或 Virtual Private Database 的访问控制来分别防止 DBA 或其他用户看到数据,并使用透明数据加密来加密静态数据(操作系统/文件级加密)。这不仅可以防止 DBA 查看数据,还可以防止更改或删除数据。

如果您无论如何都想加密数据值,那么所有加密/解密和密钥管理都应在外部从 DBA 无法访问加密密钥的数据库中处理。其工作原理取决于您的应用程序设计和编程语言的选择。请注意,构建强大的加密和密钥管理架构不是简单的练习...

还要注意,包装 PL/SQL 源代码只是代码的混淆,而不是加密。可以使用任意数量的现有网站或内部存储过程轻松对其进行反转。真正的 DBA 还应该拥有 execute any procedure 权限,或者能够授予自己显式权限以执行任何解密功能,甚至不必关心密钥是什么(只有 Database Vault 可以防止这种情况发生)。

将密钥作为输入而不是将其直接嵌入代码中也会有问题,因为 DBA 可以通过多种方式查看您的 SQL。当通过 SQL 查询传输时,密钥也可能在 ADDM 报告、数据库跟踪文件或审计跟踪中公开。

没有安全的方式来处理加密,正如您使用 PL/SQL 描述的那样,它还可以保护数据免受 DBA 的侵害。

【讨论】:

  • @pmdba:你的意思是什么:“......甚至不必关心密钥是什么......”?
  • @Robbi 如果(如所述)密钥嵌入在数据库中的函数 in 中,那么 DBA - 或任何其他能够执行该函数的人 - 可以简单地运行它并不需要知道关键是什么。这是设计的。使用位于 数据库中的密钥加密数据根本不会为具有提升权限的 DBA 等用户提供任何安全性,因为他们将始终能够执行功能,除非数据库Vault 被部署来限制它们。唯一的其他安全方法是将密钥和加密功能放在 DBA 无法访问的应用程序中。
  • 注意:仅将密钥放在数据库之外没有帮助,因为密钥必须作为 SQL 语句的一部分传输到函数,DBA然后将能够读取并从中获取密钥。
  • ok,把密钥放在加密函数里面不太聪明。正如您所指出的,最好的办法是使用本机语言实现加密功能,然后使用驱动程序(如 ODBC)将结果存储在 DB 中。我做对了吗?
  • 是的,或者部署 Database Vault。使用 DB Vault 的优势在于无需修改应用程序代码即可部署它,不会影响性能或授权用户使用 SQL 搜索数据的能力。加密数据值(无论是在应用程序还是数据库中)会引入处理开销,并且无法使用 SQL 直接搜索加密数据。我只会对只会单独处理的行中的列执行此操作,而不是批量处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-14
  • 2021-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多