参考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[] ...{ 0, 0, 0, 0, 0, 0, 0, 0 });
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 varchar2) return 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 RAW) return 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 解密。