Oracle自带的wallet功能,确实能实现数据的密文存储,但有没有那种能够
保密后的数据DBA看不了,且对于应用更是透明,且底层密文存储,有相关想法的,
过来一起讨论啊!

解决方案 »

  1.   


    --之前我也做过此类加密的研究,是根据我们自己现有的平台进行加密的。
    --后头由于实现起来复杂,未采用Oracle的加密技术,而是单独分开来建立一个独立的数据库,从而达到数据库的透明加密
    --下面是当时一点文档,供你参考下:--方案一:
    Oracle从8i开始提供一个数据加密包:dbms_obfuscation_toolkit。利用这个包,我们可以对资料进行DES,Triple DES或者MD5加密。由于考虑到MD5加密是不可逆的,所以不采用MD5加密方式。1、思路:
    在需要加密字段的表中,增加对应的加密后的密文字段。例如表users中有字段salary需要加密,则增加新字段encrypted存放加密后的内容,而原salary的内容设为0值或者删除。 2、具体来说:
    自己编写PL/SQL代码,主要是产生密钥和提供加密解密的function,其中加密解密的function调用Oracle8i提供的数据加密包:dbms_obfuscation_toolkit。从而使数据得到加解密。

    3、测试案例:
    (1)、新建了一个SWING的单屏幕,在SF_POST_QUERY_OF_EACH_ROW()方法中调用Oracle已经建立好的function,对解密字段进行解密之后,再显示在屏幕相应的字段上。
    (2)、当进行insert或者update存盘,在SF_POST_DATABASE_COMMIT()方法中,调用加密function进行加密,然后存入数据库。 4、遇到的问题:
    (1)查询的时候,由于在SF_POST_QUERY_OF_EACH_ROW()方法中解密后,又往屏幕中字段进行了set动作,导致屏幕的状态改变,最终导致屏幕存盘后会出现数据错误。
    举例说明:假设数据库已经有5笔数据,点击查询按钮进行解密,然后再SET进相应的屏幕字段,现在屏幕中显示的都是明文;接着进行“修改”第5笔数据,然后存盘,就会导致前四笔明文数据存入数据库中,数据库中前四笔资料就保存的是明文,而修改的第五笔就是密文。最后如果再点击“查询”的时候,在解密的时候就会出错,因为对明文进行解密就逻辑错误。
    (2)这样做的效率比较低,因为每次都要在Java程序里调用解密,然后存盘时候又调用加密。
    针对这个问题,我想如果用trigger去实现就比较好了。也就是说,insert、update动作存档后,Oracle自动触发trigger去执行加密动作,而不需要在Java程序中调用Oracle的加密function进行加密后再存入数据库。
    经过测试,在同一张表上,创建trigger是不能实现的。也就是说,Oracle规定,不能对trigger的触发表进行操作。还有,如果用自治事务去实现,同样在update动作的时候会造成dead lock发生。
    5、下一步解决方向:
    (1)改变思路:
    也就是说,原来的基本表不作任何改动,增加的密文字段字段也不要保存在基本表中,针对每一个需要加密的字段,我们重新建立一张表,这张表保存基表的主键和密文。
    (2)这样作了改变之后,我们就能创建trigger自动实现进入数据库的时候,自动加密保存,就不需要在屏幕Java程序中写代码。
    (3)屏幕中查询的时候,由于另一张密文表与基表存在主键的关联关系,在SF_POST_QUERY_OF_EACH_ROW()方法中进行解密的时候,我们从密文表中读取密文,进行解密之后,再set进屏幕字段。
    同时,即便我查询出5笔数据都是明文,修改其中一笔资料,再存盘。由于数据库底层我们创建的有trigger进行加密,所以就避免了明文被存入数据库的情况。
    (4)此种改变后的思路和测试案例正在测试,同时还会针对MD屏幕进行测试。但是,这样可能会造成效率比较低,因为我只修改了第5笔数据,存盘时候,trigger就会加密所有数据,造成trigger做了一些无用的动作,但这又是必须的!否则会将明文存入数据库。
    --方案二:透明数据加密TDE
    从Oracle10g R2开始,提供了一种透明数据加密技术(Transparent Data Encryption,TDE)。此种加密技术,需要具有alter system权限,进行打开和关闭“钱夹”,从而实现加密解密。
    由于考虑到需求(DBA也不能查看加密字段),所有此种加密技术被否定!
      

  2.   

    自定义加密函数,吧函数写在应用里就可以了,DBA肯定看不到,对应用就透明了
      

  3.   

    5、下一步解决方向:
    (1)改变思路:
        也就是说,原来的基本表不作任何改动,增加的密文字段字段也不要保存在基本表中,针对每一个需要加密的字段,我们重新建立一张表,这张表保存基表的主键和密文。
    (2)这样作了改变之后,我们就能创建trigger自动实现进入数据库的时候,自动加密保存,就不需要在屏幕Java程序中写代码。
    (3)屏幕中查询的时候,由于另一张密文表与基表存在主键的关联关系,在SF_POST_QUERY_OF_EACH_ROW()方法中进行解密的时候,我们从密文表中读取密文,进行解密之后,再set进屏幕字段。
        同时,即便我查询出5笔数据都是明文,修改其中一笔资料,再存盘。由于数据库底层我们创建的有trigger进行加密,所以就避免了明文被存入数据库的情况。
    (4)此种改变后的思路和测试案例正在测试,同时还会针对MD屏幕进行测试。但是,这样可能会造成效率比较低,因为我只修改了第5笔数据,存盘时候,trigger就会加密所有数据,造成trigger做了一些无用的动作,但这又是必须的!否则会将明文存入数据库。经评估,该解决方法主要有两个问题不能解决:
    A、如果查询出10笔资料,只修改一笔,在存档的同时会把其它九笔的文明更新到资料库,这就会引起后面Trigger九次无用的加密动作,效率很低。
    B、在修改一笔资料后,存档,紧接着再修改,再存档的时候就会抛出异常。该异常是由于在第一次存档后平台有一个将数据库中的明文清零的动作,造成了平台底层的数据集和资料库中的资料不一致,发生数据冲突而造成的。但是明文清零的动作是必须做的。所以这种解决方法有一个不能解决的矛盾冲突。7、最终的解决方法:
          在基表上添加一个密文栏位,将荧幕上显示的明文设置为NONEBASE栏位,将添加的密文栏位,设置为隐藏。
          这样,查询解密的时候只会给NONEBASE栏位塞值,就不会联动修改底层的数据集,就解决了第一个问题。
     在修改的时候,给NONEBASE栏位加上事件,使其联动加密到BASE栏位,这样,数据在进数据集之前就已经加密,不会存在清零动作,所以解决了第二个问题。
          至于加解密的方法,可以用Java类加解密,也可以用PL\SQL过程加解密,最后决定还是用PL\SQL过程。因为用JAVA加解密的话,问题比较多,有效能的问题,也有维护上的问题(需要同时维护两处,一处在平台上,一处在数据中),而且还可能涉及到数据库版本的问题,故思虑再三,还是决定用PL\SQL过程来解决。接下来有两步计划:
     A、找一个具体的荧幕来做测试,看看修改过程中都会涉及那些问题。
     B、对过程本身的加密。
    7、后续计划执行:
    A、对包体加密已完成,使用ORACLE的WRAP加密,该加密为单向加密,故需保存好源码,以便之后维护。
    B、荧幕测试(BBCE):
         BBCE是一个单纯的建档荧幕,逻辑不是很复杂,下面说一下在测试的时候都做了那些动作:
    (1)修改基表TXD000BBCE1,添加一个SLYONE的薪资加密栏位,类型为VARCHAR2,长度为64(该处受到加密算法的制约,只能为8的倍数)。
    (2)修改荧幕界面,将原来的BSL(薪资)栏位隐藏掉,在存档时固定塞入1,增加BASE栏位SLYONE,用于存储密文,并隐藏掉,添加NONEBASE栏位SLYTWO,用于显示明文。
    (3)添加加解密过程,解密在SF_POST_QUERY_OF_EACH_ROW方法中调用,加密利用SWING的CaretListener事件来加密,通过该事件,监听栏位只要一有输入,就会联动加密到BASE栏位SLYONE中。比如说,我输入‘1’,事件就会把‘1’加密到BASE栏位中,紧接着再输入‘1’,事件就会把‘11’加密到BASE栏位中。
    (4)逻辑替换,把原来的BSL栏位上的逻辑,全部替换为NONEBASE栏位SLYTWO。
    (5)BASE栏位状态模拟,因为BSL是BASE栏位,而替换它的SLYTWO是NONEBASE栏位,故要编写代码,来将NONEBASE栏位SLYTWO的状态模拟为BASE栏位,比如说,在查询后是不可编辑,但新增时可编辑等。
    (6)格式化数字。对数字进行格式化,以便显示。
    C、该种方法遇到的问题
        把BASE栏位隐藏掉,在资料浏览面板就看到薪资栏位,也看不到NONEBASE栏位。  
      

  4.   

        看了“jelyon”的回贴,想法很很不错,你们有没有具体的实现啊?    
      

  5.   

        就是有没有可能,完全在数据库端实现,不用改造应用,最好还要能和Oracle执行计划索引结合起来,简单的函数索引确实能做到,但是这个对DBA可是还是能看数据啊!
        如何能防DBA??
        继续计论中……
      

  6.   

    那也简单,往简单的做,例如写个存储过程,密钥需要从字符串或者文件导入,这样虽然可以看到加密存储过程,都是DBA无密钥,也没有办法看在或者,自己在ORACLE挂载个第三方的应用包,例如写个JAVA加密和解密包,加载到ORACLE中,注意包编译进去加密,防止反编译,或者写个PRO*C 加密算法
    。。方法无数。看实际需求
      

  7.   

    oacle加密还没研究过呢! 有空的话研究下!
      

  8.   

        最近在试用一款DBCoffer的软件,它的第三方权限管理能很好防住DBA,且对部分数据的加密处理也有很好的支持,最重要的是居然能与Oracle自身的执行计划结合起来……
        有兴趣的朋友可以一起来了解下……
      

  9.   

    哎。。 dba也是预防对象了。  
      

  10.   

    记得以前有讨论过这个问题,如果DBA同时是系统管理员--root权限,基本就无解了,除非用额外的加密
      

  11.   

    没错DBA根本没办法防,很多方法拿到密匙,连编译的包都可以反编译,还有什么不能做的。
    除非不提供DBA权限