1. oracle 加密解密:
进入oracle命令行 sqlplus /as sysdba 执行赋权命令-赋权命令需在加密解密函数之前执行 grant execute on sys.dbms_crypto to crm; grant execute on sys.UTL_I18N to crm;
加密解密函数(需注意,oracle 加密后字符串是大写,代码中需要转大写处理):
-- 加密函数 CREATE OR REPLACE FUNCTION FUN_AES( V_STR VARCHAR2 , V_KEY VARCHAR2 ) RETURN VARCHAR2 AS V_KEY_RAW RAW(24) ; V_STR_RAW RAW(2000) ; V_RETURN_STR VARCHAR2(2000) ; V_TYPE PLS_INTEGER ; BEGIN V_KEY_RAW := UTL_I18N.STRING_TO_RAW(V_KEY,'UTF8') ; V_STR_RAW := UTL_I18N.STRING_TO_RAW(V_STR,'UTF8') ; V_TYPE := DBMS_CRYPTO.ENCRYPT_AES128+DBMS_CRYPTO.CHAIN_ECB+DBMS_CRYPTO.PAD_PKCS5 ; V_STR_RAW := DBMS_CRYPTO.ENCRYPT(SRC => V_STR_RAW , typ => V_TYPE, key => V_KEY_RAW) ; V_RETURN_STR := RAWTOHEX(V_STR_RAW); RETURN V_RETURN_STR ; END; / -- 解密函数 CREATE OR REPLACE FUNCTION FUN_DAES( V_STR VARCHAR2 , V_KEY VARCHAR2 ) RETURN VARCHAR2 AS V_KEY_RAW RAW(24) ; V_STR_RAW RAW(2000) ; V_RETURN_STR VARCHAR2(2000) ; V_TYPE PLS_INTEGER ; BEGIN V_KEY_RAW := UTL_I18N.STRING_TO_RAW(V_KEY,'UTF8') ; V_STR_RAW := HEXTORAW(V_STR); V_TYPE := DBMS_CRYPTO.ENCRYPT_AES128+DBMS_CRYPTO.CHAIN_ECB+DBMS_CRYPTO.PAD_PKCS5 ; V_STR_RAW := DBMS_CRYPTO.DECRYPT(SRC => V_STR_RAW , typ => V_TYPE, key => V_KEY_RAW ) ; V_RETURN_STR := UTL_I18N.RAW_TO_CHAR(V_STR_RAW,'UTF8'); RETURN V_RETURN_STR ; END; /
2. java 加密函数:
private static final String ECB_PKCS5_PADDING = "AES/ECB/PKCS5Padding";
private static final String AES = "AES";
//编码方式
public static final String CODE_TYPE = "UTF-8";
/**
* AES 加密操作 ECBPK5Hex
*
* @param content 待加密内容
* @param key 加密密钥
* @return 返回Base64转码后的加密数据
*/
public static String encryptECBPK5Hex(String content, String key) {
if (content == null || "".equals(content)) {
return content;
}
try {
/*
* 新建一个密码编译器的实例,由三部分构成,用"/"分隔,分别代表如下
* 1. 加密的类型(如AES,DES,RC2等)
* 2. 模式(AES中包含ECB,CBC,CFB,CTR,CTS等)
* 3. 补码方式(包含nopadding/PKCS5Padding等等)
* 依据这三个参数可以创建很多种加密方式
*/
Cipher cipher = Cipher.getInstance(ECB_PKCS5_PADDING);//"AES/ECB/PKCS5Padding";
byte[] byteContent = content.getBytes(CODE_TYPE);
//使用加密秘钥
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(CODE_TYPE), AES);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);// 初始化为加密模式的密码器
byte[] result = cipher.doFinal(byteContent);// 加密
return byteToHex(result);//通过hex转码返回
} catch (Exception ex) {
}
return null;
}
/**
* AES 解密操作 ECBPK5Hex
*
* @param content
* @param key
* @return
*/
public static String decryptECBPK5Hex(String content, String key) {
if (content == null || "".equals(content)) {
return content;
}
try {
//实例化
Cipher cipher = Cipher.getInstance(ECB_PKCS5_PADDING);
//使用加密秘钥
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(CODE_TYPE), AES);
cipher.init(Cipher.DECRYPT_MODE, skeySpec);// 初始化为加密模式的密码器
byte[] result = cipher.doFinal(hexToByte(content));
return new String(result, CODE_TYPE);
} catch (Exception ex) {
}
return null;
}
public static String byteToHex(byte[] bytes){
String strHex = "";
StringBuilder sb = new StringBuilder("");
for (int n = 0; n < bytes.length; n++) {
strHex = Integer.toHexString(bytes[n] & 0xFF);
sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示,位数不够,高位补0
}
return sb.toString().trim();
}
public static byte[] hexToByte(String hex){
int m = 0, n = 0;
int byteLen = hex.length() / 2; // 每两个字符描述一个字节
byte[] ret = new byte[byteLen];
for (int i = 0; i < byteLen; i++) {
m = i * 2 + 1;
n = m + 1;
int intVal = Integer.decode("0x" + hex.substring(i * 2, m) + hex.substring(m, n));
ret[i] = Byte.valueOf((byte)intVal);
}
return ret;
}
C# 版本
/// <summary> /// AES 算法加密(ECB模式) 将明文加密,加密后进行Hex编码,返回密文 /// </summary> /// <param name="str">明文</param> /// <param name="key">密钥</param> /// <returns>加密后Hex编码的密文</returns> public static string AesEncryptor_ECB_Hex(string str, string key) { if (string.IsNullOrEmpty(str)) return null; Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str); RijndaelManaged rm = new RijndaelManaged { //Key = StrToHexByte(key), //把key转成16进制 Key = Encoding.UTF8.GetBytes(key), Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }; ICryptoTransform cTransform = rm.CreateEncryptor(); Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return ToHexString(resultArray); } /// <summary> ///AES 算法解密(ECB模式) 将密文Hex解码后进行解密,返回明文 /// </summary> /// <param name="str">密文</param> /// <param name="key">密钥</param> /// <returns>明文</returns> public static string AesDecryptor_ECB_Hex(string str, string key) { if (string.IsNullOrEmpty(str)) return null; Byte[] toEncryptArray = StrToHexByte(str); RijndaelManaged rm = new RijndaelManaged { //Key = StrToHexByte(key), //key16进制解码 Key = Encoding.UTF8.GetBytes(key), Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }; ICryptoTransform cTransform = rm.CreateDecryptor(); Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Encoding.UTF8.GetString(resultArray); } /// <summary> /// byte数组Hex编码 /// </summary> /// <param name="bytes">需要进行编码的byte[]</param> /// <returns></returns> public static string ToHexString(byte[] bytes) { string hexString = string.Empty; if (bytes != null) { StringBuilder strB = new StringBuilder(); for (int i = 0; i < bytes.Length; i++) { strB.Append(bytes[i].ToString("X2")); } hexString = strB.ToString(); } return hexString; } /// <summary> /// 字符串进行Hex解码(Hex.decodeHex()) /// </summary> /// <param name="hexString">需要进行解码的字符串</param> /// <returns></returns> public static byte[] StrToHexByte(string hexString) { hexString = hexString.Replace(" ", ""); if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return returnBytes; }
测试:
static void Main(string[] args) { //密码 string message = AES_Cipher.AesEncryptor_ECB_Hex("1233211234567", "1234567890123456"); Console.WriteLine(message); System.Diagnostics.Trace.WriteLine(message); string inmsg = AES_Cipher.AesDecryptor_ECB_Hex(message, "1234567890123456"); Console.WriteLine(inmsg); System.Diagnostics.Trace.WriteLine(inmsg); }
3. 分析:
加密方式网上工具测试:
1. ECB 模式
2. pkcs5padding
3. 长度128
4. 蜜月16位
5. 输出 hex
6. 输入编码 UTF-8
4. 测试:
select FUN_ENCRYPTION128C('1233211234567','1234567890123456'),FUN_DECRYPTION128C('BEA8BDDCE00E13B8713A071C8EDFB12C','1234567890123456') from dual;
public static void main(String[] args) { String content = "1233211234567"; String key = "1234567890123456"; System.out.println("content:" + content); String s1 = EncryptRuleAESSupport.encryptORACLE(content, key); System.out.println("result1:" + s1); // s1="G8SP97HnhXIGcPvnc7ObyA"; // System.out.println("result2:" + EncryptRuleAESSupport.decrypt(s1, key)); // System.out.println("key : " + key); // System.out.println("VIPARA" + VIPARA); }