Oracle的加密

本文介绍如何在Oracle数据库中使用DES算法加密字段,并通过Hibernate框架实现加密字段的自动加解密。文中提供了Java加密类及Hibernate自定义类型的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  参考welcomyou写的<<将Oracle的加密字段映射到Hibernate>>,可以在hibernate进行save和research时候自动对数据库字段加密解密。 

由于最近项目要用到报表,oracle的存贮过程要对加密字段操作,所以要利用oracle的DES算法,并且我在进行多表操作时,习惯使用ibatis,所以也可以利用oracle加解密函数。 现在开始: 首先,建立一个执行oracle DES算法的java类. 这段列出代码的与oracle dbms_obfuscation_toolkit DES算法的加解密相同。

 

package util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import org.apache.commons.lang.ArrayUtils;

public class Encryption {

      
private Cipher en;
      
private Cipher de;

      
public byte[] encrypt(String s) {

            
try {
                  
byte[] data = s.getBytes();
                  
if (data.length % 8 != 0{
                        
int length = 8 - data.length % 8;
                        
byte[] spaces = new byte[length];
                        
for (int i = 0; i < spaces.length; i++{
                              spaces[i] 
= 0x20;
                        }

                        data 
= ArrayUtils.addAll(data, spaces);
                  }

                  
return en.doFinal(data);

            }
 catch (Exception e) {
                  
throw new RuntimeException(e);
            }

      }


      
public String decrypt(byte[] b) {

            
try {
                  
byte[] data = de.doFinal(b);
                  
return new String(data).trim();
            }
 catch (Exception e) {
                  
throw new RuntimeException(e);
            }


      }


      
private Encryption() {

            
try {
                  DESKeySpec deskey 
= new DESKeySpec("key45678".getBytes());
                  SecretKeyFactory skf 
= SecretKeyFactory.getInstance("DES");
                  SecretKey key 
= skf.generateSecret(deskey);
                  IvParameterSpec iv 
= new IvParameterSpec(new byte[] 00000000 });
                  en 
= Cipher.getInstance("DES/CBC/NoPadding");
                  en.init(Cipher.ENCRYPT_MODE, key, iv);
                  de 
= Cipher.getInstance("DES/CBC/NoPadding");
                  de.init(Cipher.DECRYPT_MODE, key, iv);

            }
 catch (Exception e) {
                  
throw new RuntimeException(e);
            }

      }


      
private static Encryption instance = new Encryption();

      
public static Encryption getInstance() {

            
return instance;

      }

}

 

  建库,注意对加密字段用raw类型,实际上varchar2不是一个好的选择,因为它不能正确的得到加密数据。

 

CREATE TABLE ZENCRYPT
(
  ID       
VARCHAR2(32)    NOT NULL,
  ENCRYPT  
RAW(32)
)

 

现在写一个类继承Hibernate UseType接口,想多了解些UseType,可以参照hibernate介绍,我看的是夏老大的《深入浅出hibernate》,虽然介绍工具好象有点旧。

 

package usertype;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
import util.Encryption;

public class EncryptType implements UserType {

       
public Object assemble(Serializable cached, Object owner) throws HibernateException {
            
return null;
      }


      
public Object deepCopy(Object value) throws HibernateException {

            
if (value == null{
                  
return null;
            }
 else {
                  
return new String((String) value);
            }

      }


      
public Serializable disassemble(Object value) throws HibernateException {

            
return null;

      }


      
public boolean equals(Object x, Object y) throws HibernateException {

            
return (x == y) || (x != null && y != null && (x.equals(y)));

      }


      
public int hashCode(Object x) throws HibernateException {
            
return x.hashCode();
      }


      
public boolean isMutable() {
            
return false;
      }


      
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {

//Get bin data from database then decrypt to String

            
byte[] data = rs.getBytes(names[0]);

            
return Encryption.getInstance().decrypt(data);

      }


      
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {

            
if (value == null{
                  
return;
            }

//Encrypt String to bin data

            
byte data[] = Encryption.getInstance().encrypt(value.toString());
            st.setBytes(index, data);
      }


      
public Object replace(Object original, Object target, Object owner) throws HibernateException {
            
return null;
      }


      
public Class returnedClass() {
            
return java.lang.String.class;
      }


      
public int[] sqlTypes() {
            
return new int[] { Types.BINARY };
      }

}

 

Mapping file

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

<hibernate-mapping>

      
<class name="entity.ZEncrypt" table="ZENCRYPT">
            
<id name="ids" type="string">
                  
<column name="ID" />
                  
<generator class="native" />
            
</id>
            
<property name="encrypt" type="usertype.EncryptType">
                  
<column name="ENCRYPT" />
            
</property>
      
</class>

</hibernate-mapping>

 

 

好了,现在执行hibernate的CRUD,就会自动对ENCRYPT字段加密和解密操作。当然上面还要有你的vo,两个属性都是String就可以。下面是oracle函数,如果用ibatis查找也可以使用。在toad的procs下有Functions,在这新建encrypt和decrypt两个函数,代码:

CREATE OR REPLACE function encrypt (i_password varchar2return RAW is
v_encrypted_val 
varchar2(38);
v_data 
varchar2(38);
c_encrypt_key 
varchar2(8) := 'key45678';
vEncryptedRaw 
Raw(2048);
begin
-- Input data must have a length divisible by eight
v_data := RPAD(i_password,(TRUNC(LENGTH(i_password)/8)+1)*8,' ');

DBMS_OBFUSCATION_TOOLKIT.DESENCRYPT(
input_string 
=> v_data,
key_string 
=> c_encrypt_key,
encrypted_string 
=> v_encrypted_val);
vEncryptedRaw :
= UTL_RAW.CAST_TO_RAW(v_encrypted_val);
return vEncryptedRaw;
end encrypt;
/

 

 

CREATE OR REPLACE function decrypt (i_password RAWreturn varchar2 is
v_decrypted_val 
varchar2(38);
c_encrypt_key 
varchar2(8) := 'key45678';

begin
DBMS_OBFUSCATION_TOOLKIT.DESDECRYPT(
input_string 
=> UTL_RAW.CAST_TO_VARCHAR2(i_password),
key_string 
=> c_encrypt_key,
decrypted_string 
=> v_decrypted_val);
return v_decrypted_val;
end decrypt;
/

 

执行sql:select decrypt(ENCRYPT) from ZENCRYPT 则会对加密后的字段ZENCRYPT 解密。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值