使用加密的LOB文件加载Oracle表,然后对其进行解密

时间:2015-03-25 16:55:03

标签: oracle encryption plsql sql-loader dbms-crypto

我正在获得一个包含1000万行数据的大型加密文件。

我需要将其加载到oracle数据库(以其加密形式),然后使用pl / sql和oracle内置dbms_crypto在数据库中解密。

然后我需要处理未加密的LOB以分离出1000万行。

我将拥有该文件的公钥。该文件大小约为5GB。 这可能只使用pl / sql吗? (和oracle内置插件)

有没有人有过做这种事的经历? - 任何指针都会受到欢迎。

谢谢

1 个答案:

答案 0 :(得分:1)

这适合我。

SYS必须:

GRANT EXECUTE ON DBMS_CRYPTO TO <user>

在用户中:

CREATE OR REPLACE DIRECTORY
CRYPTDIR AS
'<crypted files directory>';

CREATE TABLE TESTCRYPT (ID INTEGER, E BLOB, D BLOB);

CREATE OR REPLACE FUNCTION load_Blob_FromFile(p_file_name VARCHAR2) 
RETURN BLOB
AS
   dest_loc  BLOB := empty_blob();
   src_loc   BFILE := BFILENAME('CRYPTDIR', p_file_name);
BEGIN
   -- Open source binary file from OS
   DBMS_LOB.OPEN(src_loc, DBMS_LOB.LOB_READONLY);

   -- Create temporary LOB object
   DBMS_LOB.CREATETEMPORARY(
         lob_loc => dest_loc
       , cache   => true
       , dur     => dbms_lob.session
   );

   -- Open temporary lob
   DBMS_LOB.OPEN(dest_loc, DBMS_LOB.LOB_READWRITE);

   -- Load binary file into temporary LOB
   DBMS_LOB.LOADFROMFILE(
         dest_lob => dest_loc
       , src_lob  => src_loc
       , amount   => DBMS_LOB.getLength(src_loc));

   -- Close lob objects
   DBMS_LOB.CLOSE(dest_loc);
   DBMS_LOB.CLOSE(src_loc);

   -- Return temporary LOB object
   RETURN dest_loc;
END;
/

插入TESTCRYPT (ID,E) SELECT 1,LOAD_BLOB_FROMFILE('EncryptedFile')FROM DUAL;


CREATE OR REPLACE FUNCTION DCRYPT2(TO_DECRYPT IN BLOB) RETURN BLOB
IS
  DECRYPTED BLOB;
  v_key  PLS_INTEGER :=
      DBMS_CRYPTO.ENCRYPT_AES128 +
      DBMS_CRYPTO.CHAIN_ECB +
      DBMS_CRYPTO.PAD_PKCS5;
BEGIN
dbms_lob.createtemporary(DECRYPTED,true);
DBMS_CRYPTO.DECRYPT(DECRYPTED,
                    TO_DECRYPT,
                     v_key,
                     '<Hex-Key>'
                    );
RETURN DECRYPTED;
END;

UPDATE TESTCRYPT SET D = DCRYPT2(E)WHERE ID = 1;


CREATE OR REPLACE FUNCTION PADIS_MASTER.blob2clob (p_in blob) RETURN clob IS
     v_clob    clob;
     v_varchar VARCHAR2(32767);
     v_start   PLS_INTEGER := 1;
     v_buffer  PLS_INTEGER := 32767;
   BEGIN
     dbms_lob.createtemporary(v_clob, TRUE);
     FOR i IN 1..CEIL(dbms_lob.getlength(p_in) / v_buffer)
     LOOP
       v_varchar := utl_raw.cast_to_varchar2(dbms_lob.SUBSTR(p_in, v_buffer, v_start));
       dbms_lob.writeappend(v_clob, LENGTH(v_varchar), v_varchar);
       v_start := v_start + v_buffer;
     END LOOP;
     RETURN v_clob;
   END;
/

SELECT BLOB2CLOB(D)FROM TESTCRYPT WHERE ID = 1;


例如Oracle 11使用此密钥编译:'b1b7adc285e82db81ea17f7be706e4f7'

最后加密功能:

CREATE OR REPLACE FUNCTION ECRYPT(TO_CRYPT IN BLOB) RETURN BLOB
IS
 CRYPTED BLOB;
 v_key  PLS_INTEGER :=  DBMS_CRYPTO.ENCRYPT_AES128 
                      + DBMS_CRYPTO.CHAIN_ECB 
                      + DBMS_CRYPTO.PAD_PKCS5;
BEGIN
 dbms_lob.createtemporary(AUSGABE,true);
 DBMS_CRYPTO.ENCRYPT(CRYPTED,
                     TO_CRYPT,
                     v_key,
                     'b1b7adc285e82db81ea17f7be706e4f7'
                    );
 RETURN CRYPTED;
END;