• oracle AES加密 和 java AES加密 C#加密解密互通的问题


    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);
    
        }
  • 相关阅读:
    我回来了
    wget 官方jdk
    linux rpm命令安装卸载 初步使用
    关于一些对location认识的误区(转)
    直接插入排序
    冒泡排序
    Wireshark下TCP三次握手四次挥手
    linux内存使用率详解
    Linux下硬盘使用率详解及shell脚本实现
    Linux下CPU使用率详解
  • 原文地址:https://www.cnblogs.com/leolzi/p/16199631.html
Copyright © 2020-2023  润新知