寫在前面
實際情況中,有些不適用於在Java代碼層面處理的事,比如數據庫表外部系統同步到本庫時,入庫前需加密處理。不太好考慮用Java業務層面上做,就需要在數據庫方入庫調用相關的業務邏輯進行處理,比如用戶表信息的加密,以下就以Oracle調用Java代碼展開。
第一步在Java層面實現
SecureUtil.java
import java.security.Key;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import com.sun.crypto.provider.SunJCE;
/**
* Oracle上的加密類
* @author laiqi
*
*/
public class SecureUtil {
/**
* IDC系統採用的加解密方法,
* @param str 加解密字符串
* @param encrypt 是否加密,true爲加密,false爲解密
* @return 加解密字符串結果
* @throws Exception
*/
public static String sysEncodes(String str, String flag) throws Exception{
return "true".equalsIgnoreCase(flag) ? new DES("tissonco").encrypt(str) : new DES("tissonco").decrypt(str);
}
}
class DES {
private static String strDefaultKey = "national";
private Cipher encryptCipher;
private Cipher decryptCipher;
public static String byteArr2HexStr(byte[] arrB) throws Exception {
int iLen = arrB.length;
StringBuffer sb = new StringBuffer(iLen * 2);
for (int i = 0; i < iLen; ++i) {
int intTmp;
for (intTmp = arrB[i]; intTmp < 0; intTmp += 256) {
;
}
if (intTmp < 16) {
sb.append("0");
}
sb.append(Integer.toString(intTmp, 16));
}
return sb.toString();
}
public static byte[] hexStr2ByteArr(String strIn) throws Exception {
byte[] arrB = strIn.getBytes();
int iLen = arrB.length;
byte[] arrOut = new byte[iLen / 2];
for (int i = 0; i < iLen; i += 2) {
String strTmp = new String(arrB, i, 2);
arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
}
return arrOut;
}
public DES() throws Exception {
this(strDefaultKey);
}
public DES(String strKey) throws Exception {
this.encryptCipher = null;
this.decryptCipher = null;
Security.addProvider(new SunJCE());
Key key = this.getKey(strKey.getBytes());
this.encryptCipher = Cipher.getInstance("DES");
this.encryptCipher.init(1, key);
this.decryptCipher = Cipher.getInstance("DES");
this.decryptCipher.init(2, key);
}
public byte[] encrypt(byte[] arrB) throws Exception {
return this.encryptCipher.doFinal(arrB);
}
public String encrypt(String strIn) throws Exception {
return byteArr2HexStr(this.encrypt(strIn.getBytes()));
}
public byte[] decrypt(byte[] arrB) throws Exception {
return this.decryptCipher.doFinal(arrB);
}
public String decrypt(String strIn) throws Exception {
return new String(this.decrypt(hexStr2ByteArr(strIn)));
}
private Key getKey(byte[] arrBTmp) throws Exception {
byte[] arrB = new byte[8];
for (int key = 0; key < arrBTmp.length && key < arrB.length; ++key) {
arrB[key] = arrBTmp[key];
}
SecretKeySpec arg3 = new SecretKeySpec(arrB, "DES");
return arg3;
}
}
第二步在Oracle層面定義Java sources
Java sources中新建:
create or replace and compile java source named SecureUtil as
import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.Key;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import com.sun.crypto.provider.SunJCE;
public class SecureUtil {
/**
* IDC系統採用的加解密方法,
* @param str 加解密字符串
* @param encrypt 是否加密,true爲加密,false爲解密
* @return 加解密字符串結果
* @throws Exception
*/
public static String sysEncodes(String str, String flag) throws Exception{
return "true".equalsIgnoreCase(flag) ? new DES("tissonco").encrypt(str) : new DES("tissonco").decrypt(str);
}
}
class DES {
private static String strDefaultKey = "national";
private Cipher encryptCipher;
private Cipher decryptCipher;
public static String byteArr2HexStr(byte[] arrB) throws Exception {
int iLen = arrB.length;
StringBuffer sb = new StringBuffer(iLen * 2);
for (int i = 0; i < iLen; ++i) {
int intTmp;
for (intTmp = arrB[i]; intTmp < 0; intTmp += 256) {
;
}
if (intTmp < 16) {
sb.append("0");
}
sb.append(Integer.toString(intTmp, 16));
}
return sb.toString();
}
public static byte[] hexStr2ByteArr(String strIn) throws Exception {
byte[] arrB = strIn.getBytes();
int iLen = arrB.length;
byte[] arrOut = new byte[iLen / 2];
for (int i = 0; i < iLen; i += 2) {
String strTmp = new String(arrB, i, 2);
arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
}
return arrOut;
}
public DES() throws Exception {
this(strDefaultKey);
}
public DES(String strKey) throws Exception {
this.encryptCipher = null;
this.decryptCipher = null;
Security.addProvider(new SunJCE());
Key key = this.getKey(strKey.getBytes());
this.encryptCipher = Cipher.getInstance("DES");
this.encryptCipher.init(1, key);
this.decryptCipher = Cipher.getInstance("DES");
this.decryptCipher.init(2, key);
}
public byte[] encrypt(byte[] arrB) throws Exception {
return this.encryptCipher.doFinal(arrB);
}
public String encrypt(String strIn) throws Exception {
return byteArr2HexStr(this.encrypt(strIn.getBytes()));
}
public byte[] decrypt(byte[] arrB) throws Exception {
return this.decryptCipher.doFinal(arrB);
}
public String decrypt(String strIn) throws Exception {
return new String(this.decrypt(hexStr2ByteArr(strIn)));
}
private Key getKey(byte[] arrBTmp) throws Exception {
byte[] arrB = new byte[8];
for (int key = 0; key < arrBTmp.length && key < arrB.length; ++key) {
arrB[key] = arrBTmp[key];
}
SecretKeySpec arg3 = new SecretKeySpec(arrB, "DES");
return arg3;
}
}
第三步在Oracle層面定義Functions
新建函數:
create or replace function SecureUtil(str varchar2,flag varchar2) return varchar2
as language java name 'SecureUtil.sysEncodes(java.lang.String,java.lang.String) return java.lang.String';
第四步測試調用
執行
--加密
select SecureUtil('135355201110', 'true') from dual;
--解密
select SecureUtil('d4f16b6c3f7c32ab14d964a36c824657', 'false') from dual;
注,過程中出現
the Permission (java.security.SecurityPermission insertProvider.SunJCE) has not been granted to NEWIDC. The PL/SQL to grant this is dbms_java.grant_permission( ‘NEWIDC’, ‘SYS:java.security.SecurityPermission’, ‘insertProvider.SunJCE’, ‘’ )
需執行exec dbms_java.grant_permission( 'NEWIDC', 'SYS:java.security.SecurityPermission', 'insertProvider.SunJCE', '' );