Oracle中加密PL/SQL代码


下面不才根据Oracle官方文档讲解一下如何加密PL/SQL代码,希望大家共同学习:

主要内容包含以下三块:

  • What is Obfuscation?

  • Obfuscating PL/SQL Code With the wrap Utility

  • Obfuscating PL/QL Code With DBMS_DDL Subprograms

一、什么叫加密(二进制文件的混淆技术混淆 Obfuscation)?

加密一个PL/SQL单元就是隐藏PL/SQL代码的过程。可以使用oracle提供的wrap工具和DBMS_DDL进行加密。

wrap工具在命令行运行来处理一个输入的SQL 文件,例如SQL*PLUS的安装脚本。DBMS_DDL子程序加密单个动态生成的PL/SQL 单元,例如一个‘CREATE PROCEDURE’声明。

       加密的优点:

     1. 防止其他开发人员滥用你的应用或者商业竞争者偷看你的逻辑。

     2. 加密后即使通过USER_SOURCE、ALL_SOURCE或者DBA_SOURCE数据字典看不见源代码  。

     3. SQL*PLUS可以处理加密后的程序。

     4. 导入导出工具也支持加密代码,你可以备份或者移动已经加密的存储过程。     

      对加密的一些提示:

     1. 当加密一个包或者对象类型,只加密包体不加密声明。这就允许开发人员看见将要使用的包或类型的声明,但是看不到实现。

     2. 加密后的源码不可以编辑,如果要修改可以编辑源代码,然后再加密。你也可以推迟加密操作到源代码最终被应用。

     3. 为了确保所有重要的源代码都被加密,最好加密后在编辑器中查看确认。 

     加密方法的局限性:

     1.  虽然加密帮助隐藏源程序的逻辑并且使解密变的异常困难,Oracle并不推荐使用该方法加密用户密码和表名。

        加密PL/SQL代码不能绝对阻止一切试图查看源代码的操作。

      2. 加密不支持触发器,为了隐藏一个触发器的工作,我们可以写一个one-line触发器来调用已经加密的存储过程。

      3. 加密的过程并不会去检查PL/SQL代码中的语法或者语义上的错误,例如表或视图不存在。这些错误只有在编译或执行的时候才会检查被发现。

      4. 被加密的PL/SQL程序不能导入到低版本的数据库中,Oracle支持是向上兼容,不支持向下兼容。例如,你能装载在V8.15上加密过的文件到

           V8.16,但是反过来就不行!

      5. 由于源代码是PL/SQL编译器解析,而不是SQL*PLUS,所以要使用wrap工具加密的PL/SQL代码中不能使用SQL*PLUS符号声明的替代变量。

      6. 绝大多数的注释将在加密的文件中去处。See "Input and Output Files for the PL/SQL wrap Utility".

      7.如果调用DBMS_SQL.PARSE方法解析已通过DBMS_DDL.WRAP加密的PL/SQL单元时遇到语句使用了超过32767的VARCHAR2文本类型 ,需要设置LFFLG参数为

     FALSE。否则DBMS_SQL.PARSE往加密的单元中新增行将会破坏程序单元! 

二、使用WRAP工具加密PL/SQL代码:

       wrap工具介绍:

       1. warp只处理PL/SQL块,不会处理匿名块或者触发器或者非PL/SQL块。

       2. 语法如下:

       wrap iname=input_file [oname=output_file]      注:等号左右不能有空格

       input_file 是包含SQL语句的文件名,扩展名不写默认为.sql,也可以使用其他扩展格式:

       例如:

   wrap iname=/mydir/myfile
   wrap iname=/mydir/myfile.sql
   wrap iname=/mydir/myfile.src

      output_file 是加密后生成的文件名,扩展名为.pld。也可以使用其他扩展格式:

      例如:

   wrap iname=/mydir/myfile.sql oname=/mydir/myfile.plb

   wrap iname=/mydir/myfile oname=/yourdir/yourfile.out 

       wrap使用案例:

       For example, assume that the wrap_test.sql file contains the following:

  1. CREATE OR REPLACE PROCEDURE wraptest IS  
  2.   TYPE emp_tab IS TABLE OF employees%ROWTYPE INDEX BY PLS_INTEGER;  
  3.   all_emps      emp_tab;  
  4. BEGIN  
  5.   SELECT * BULK COLLECT INTO all_emps FROM employees;  
  6.   FOR i IN 1..10 LOOP  
  7.     DBMS_OUTPUT.PUT_LINE('Emp Id: ' || all_emps(i).employee_id);  
  8.   END LOOP;  
  9. END;  
  1. SQL> conn hr/hr  
  2. 已连接。      
  1. SQL> set serveroutput on size 10000  
  2. SQL> exec wraptest;  
  3. Emp Id: 198  
  4. Emp Id: 199  
  5. Emp Id: 200  
  6. Emp Id: 201  
  7. Emp Id: 202  
  8. Emp Id: 203  
  9. Emp Id: 204  
  10. Emp Id: 205  
  11. Emp Id: 206  
  12. Emp Id: 100  
  13.   
  14. PL/SQL 过程已成功完成。  

加密过程如下:

1. 保存wraptest.sql文件到d盘根目录:

2.命令行中输入以下语句:

  1. C:\Documents and Settings\Administrator>wrap iname=d:\wraptest.sql oname=d:\wraptest.plb  
  2.   
  3. PL/SQL Wrapper: Release 10.2.0.1.0- Production on 星期三 8月  08 14:42:17 2012  
  4.   
  5. Copyright (c) 1993, 2004, Oracle.  All rights reserved.  
  6.   
  7. Processing d:\wraptest.sql to d:\wraptest.plb  
 
  1. SQL> @d:\wraptest.plb  
  2.   
  3. 过程已创建。  
  4.   
  5. SQL> select text from user_source where name='WRAPTEST';  
  6.   
  7. TEXT  
  8. --------------------------------------------------------------------------------   
  9. PROCEDURE wraptest wrapped  
  10. a000000  
  11. 354  
  12. abcd  
  13. abcd  
  14. abcd  
  15. abcd  
  16. abcd  
  17. abcd  
  18. abcd  
  19. abcd  
  20.   
  21. TEXT  
  22. --------------------------------------------------------------------------------   
  23. abcd  
  24. abcd  
  25. abcd  
  26. abcd  
  27. abcd  
  28. abcd  
  29. abcd  
  30. 7  
  31. 117 128  
  32. CAQiRsqvO7POVmkobrKoWY6KHoAwg+nw2SdqfC/pmDzqaC76Czjsee0Y2FIviPZGFLcwbJ7N  
  33. wi+DZ986zkouBXR0TkX+WVkl9/227jOBn74/zw/uA/uXjr0h26MzK3hQFTYpwaTZoolPt25v  
  34.   
  35. TEXT  
  36. --------------------------------------------------------------------------------   
  37. jShK/0u2ZsH8hGsdYyvzEovl/F9sP5M7LfWlNXJYdUWsYoqFgPUV2U0/Qlf4FGqGhnTNbK8K  
  38. npjoMe2p6VFYCP/LvpdUBlSr15ciUCPpTx/O/urYuJ21XrE/6+R/Cr8TiAyvYtg8EbHssCzl  
  39. mlrg  
  40.   
  41.   
  42. SQL> exec wraptest;  
  43. Emp Id: 198  
  44. Emp Id: 199  
  45. Emp Id: 200  
  46. Emp Id: 201  
  47. Emp Id: 202  
  48. Emp Id: 203  
  49. Emp Id: 204  
  50. Emp Id: 205  
  51. Emp Id: 206  
  52. Emp Id: 100  
  53.   
  54. PL/SQL 过程已成功完成。  
三、使用DBMS_DDL子程序加密PL/SQL代码:

DBMS_DDL子程序介绍:

dbms_dll包含WRAP函数和CREATE_WRAPPED存储过程来加密单独的PL/SQL块,如包声明,包体,函数,存储过程,类型声明或者类型体。这些重载的子程序提供加密动态生成的PL/SQL块的机制。

DBMS_DDL子程序使用案例:

声明以下语句,并调用DBMS_DDL进行加密:      

  1. DECLARE  
  2. -- the package_text variable contains the text to create the package spec and body   
  3.   package_text VARCHAR2(32767);  
  4.   FUNCTION generate_spec (pkgname VARCHAR2) RETURN VARCHAR2 AS  
  5.   BEGIN  
  6.      RETURN 'CREATE PACKAGE ' || pkgname || ' AS  
  7.        PROCEDURE raise_salary (emp_id NUMBER, amount NUMBER);  
  8.        PROCEDURE fire_employee (emp_id NUMBER);  
  9.        END ' || pkgname || ';';  
  10.   END generate_spec;  
  11.   FUNCTION generate_body (pkgname VARCHAR2) RETURN VARCHAR2 AS  
  12.   BEGIN  
  13.      RETURN 'CREATE PACKAGE BODY ' || pkgname || ' AS  
  14.        PROCEDURE raise_salary (emp_id NUMBER, amount NUMBER) IS  
  15.        BEGIN  
  16.          UPDATE employees SET salary = salary + amount WHERE employee_id = emp_id;  
  17.        END raise_salary;  
  18.        PROCEDURE fire_employee (emp_id NUMBER) IS  
  19.        BEGIN  
  20.          DELETE FROM employees WHERE employee_id = emp_id;  
  21.        END fire_employee;  
  22.        END ' || pkgname || ';';  
  23.   END generate_body;  
  24.   
  25. BEGIN  
  26.   package_text := generate_spec('emp_actions'); -- generate package spec   
  27.   SYS.DBMS_DDL.CREATE_WRAPPED(package_text);  -- create and wrap the package spec   
  28.   package_text := generate_body('emp_actions'); -- generate package body   
  29.   SYS.DBMS_DDL.CREATE_WRAPPED(package_text); -- create and wrap the package body   
  30. END;  
  31. /  
 
  1. SQL> select salary from employees where employee_id=120;  
  2.   
  3.     SALARY  
  4. ----------   
  5.       8000  
  6.   
  7. SQL> exec emp_actions.raise_salary(120,100);  
  8.   
  9. PL/SQL 过程已成功完成。  
  10.   
  11. SQL> select salary from employees where employee_id=120;  
  12.   
  13.     SALARY  
  14. ----------   
  15.       8100  
查看USER_SOURCE中 emp_actions包的源代码是否加密:
  1. SQL> SELECT text FROM USER_SOURCE WHERE name = 'EMP_ACTIONS';  
  2.   
  3. TEXT  
  4. -------------------------------------------------------------------   
  5. -------------------------------------------------------------------   
  6. -------------------------------------------------------------------   
  7. -------------------------------------------------------------------   
  8. -------------------------------------------------------------------   
  9.   
  10. PACKAGE emp_actions wrapped  
  11. a000000  
  12. 354  
  13. abcd  
  14. abcd  
  15. abcd  
  16. abcd  
  17. abcd  

...............

---------------------------------------------------

made by dylan.

相关内容