zoukankan      html  css  js  c++  java
  • 加密算法-对称加密,支持解密;

    前言

    目前市面上的加密算法,有很多,什么AES,什么MD5,等,

    有的能反解密,有的不能反解密;

    加密的目的是为了增加盗取数据的难度。比如密码;

    增加截包数据分析难度;不在是明文发送;

    思路

    为了前端(u3D,C#代码)和后端java代码,统一版本保持高一致性;保证不出错,加密过程便于自己控制;

    我是一个假程序猿,喜欢自己制造代码!

    最初思路是,采用base64位对字符串进行一次处理,但是,我们都知道base64,很容易就被发现,而且也很容易就被解析了;

    这样的处理方式,只是做了一次数据格式转化,并能算是加密方式;

    第一次改造

    本思路其实就是按照一般的字符串对称性替换字符位置,进行加密;

     1         /// <summary>
     2         /// AES 对称加密
     3         /// </summary>
     4         /// <param name="str"></param>
     5         /// <param name="kk"></param>
     6         /// <returns></returns>
     7         public static String Convert_AES(String str)
     8         {
     9             char[] strChars = str.ToCharArray();
    10             /*二分对称性*/
    11             int fcount = strChars.Length / 2;
    12             /*间隔一个字符,替换*/
    13             for (int i = 0; i < fcount; i += 2)
    14             {
    15                 /*对称处理*/
    16                 char tmp = strChars[i];
    17                 strChars[i] = strChars[fcount + i];
    18                 strChars[fcount + i] = tmp;
    19             }
    20             return new String(strChars);
    21         }

    代码对字符串进行了一次对称的换位的替换;

    这样代码,虽然实现了功能,但是发现很容易就能解密了,因为都是固定的,

    而且这样代码有一个问题,在于,第一次执行后获得加密字符串1,如果把字符串1再次加密,发现其实被解密了;由于对称性问题,又被替换会原始字符串了,

    第二次改造

    基于上面代码有了第二次的改造;

     1         /// <summary>
     2         /// AES 对称加密
     3         /// </summary>
     4         /// <param name="str"></param>
     5         /// <param name="kk"></param>
     6         /// <returns></returns>
     7         public static String Convert_AES(String str, int kk)
     8         {
     9             char[] strChars = str.ToCharArray();
    10             /*二分对称性*/
    11             int fcount = strChars.Length / 2;
    12             /*间隔一个字符,替换*/
    13             for (int i = 0; i < fcount; i += kk)
    14             {
    15                 /*对称处理*/
    16                 char tmp = strChars[i];
    17                 strChars[i] = strChars[fcount + i];
    18                 strChars[fcount + i] = tmp;
    19             }
    20             return new String(strChars);
    21         }

    这样,当我们第一次加密 kk=2 ,然后再次加密 kk=3,这样得到的就完全是两个字符串,

    反码顺序就是 优先 kk =3 ,然后在 kk = 2 ;这样就能得到原始字符串了,

    但还是发现一个问题,当需要加密操作多过1次,那么字符的频繁转化缺点就暴露出来了;

    第三次改造

    我们直接把kk参数改为动态数组

     1         /// <summary>
     2         /// AES 对称加密
     3         /// </summary>
     4         /// <param name="str"></param>
     5         /// <param name="kk"></param>
     6         /// <returns></returns>
     7         public static String Convert_AES(String str, params int[] kk)
     8         {
     9             char[] strChars = str.ToCharArray();
    10             /*二分对称性*/
    11             int fcount = strChars.Length / 2;
    12             /*对称性 k 值*/
    13             foreach (int k in kk)
    14             {
    15                 /*间隔一个字符,替换*/
    16                 for (int i = 0; i < fcount; i += k)
    17                 {
    18                     /*对称处理*/
    19                     char tmp = strChars[i];
    20                     strChars[i] = strChars[fcount + i];
    21                     strChars[fcount + i] = tmp;
    22                 }
    23             }
    24             return new String(strChars);
    25         }

    这样减少了字符转化和构造的次数,以达到提升性能的一个目的;

    然后我测试下来发现,原始字符串必须要处理base64,再进行加密才有意义,不然还是明文处理形式;

    第四次改造

    加入原始字符串,编码base64位字符串后,然后再进行对称加密操作;

     1         /// <summary>
     2         /// AES 对称加密
     3         /// </summary>
     4         /// <param name="str"></param>
     5         /// <param name="kk"></param>
     6         /// <returns></returns>
     7         public static String Convert_In_AES(String str, params int[] kk)
     8         {
     9             byte[] bytes = Encoding.UTF8.GetBytes(str);
    10             long arrayLength = (long)((4.0d / 3.0d) * bytes.Length);
    11             // 如果数组长度不可被4整除,则增加.
    12             if (arrayLength % 4 != 0)
    13             {
    14                 arrayLength += 4 - arrayLength % 4;
    15             }
    16 
    17             char[] base64CharArray = new char[arrayLength];
    18             /*优先转化base64*/
    19             Convert.ToBase64CharArray(bytes, 0, bytes.Length, base64CharArray, 0);
    20             /*再加密*/
    21             return new String(Convert_AES(base64CharArray, kk));
    22         }
    23 
    24         /// <summary>
    25         /// AES 对称加密
    26         /// </summary>
    27         /// <param name="str"></param>
    28         /// <param name="kk"></param>
    29         /// <returns></returns>
    30         public static String Convert_Un_AES(String str, params int[] kk)
    31         {
    32             char[] charArray = str.ToCharArray();
    33             /*先解密*/
    34             charArray = Convert_AES(charArray);
    35             /*转化base64*/
    36             byte[] bytes = Convert.FromBase64CharArray(charArray, 0, charArray.Length);
    37             return Encoding.UTF8.GetString(bytes);
    38         }
    39 
    40 
    41         /// <summary>
    42         /// AES 对称加密
    43         /// </summary>
    44         /// <param name="str"></param>
    45         /// <param name="kk"></param>
    46         /// <returns></returns>
    47         public static char[] Convert_AES(char[] strChars, params int[] kk)
    48         {
    49             /*二分对称性*/
    50             int fcount = strChars.Length / 2;
    51             /*对称性 k 值*/
    52             foreach (int k in kk)
    53             {
    54                 /*间隔一个字符,替换*/
    55                 for (int i = 0; i < fcount; i += k)
    56                 {
    57                     /*对称处理*/
    58                     char tmp = strChars[i];
    59                     strChars[i] = strChars[fcount + i];
    60                     strChars[fcount + i] = tmp;
    61                 }
    62             }
    63             return strChars;
    64         }

    加入base64 的处理后,那么加密之前,转化成base64字符串,然后在对称加密,

    解密,先对称解密,然后再转化base64,这样,如果还能解析数据,除非他知道你的对称加密过程了,也就说秘钥;

    调用形式

    1             /*加密的对称属性*/
    2             Convert_In_AES("1234567890agasdgasfas案发后暗哨", 3, 2, 5, 6);
    3             /*解密的对称属性*/
    4             Convert_Un_AES("1234567890agasdgasfas案发后暗哨", 6, 5, 2, 3);

    到目前为止,加密算法就算完成了,

    下面附上java版本;

      1     private static final Base64.Encoder BASE64_ENCODER = java.util.Base64.getEncoder();
      2 
      3     /**
      4      * 编码64位
      5      *
      6      * @param str
      7      * @return
      8      */
      9     public static String convertToBase64String(String str) {
     10         try {
     11             return BASE64_ENCODER.encodeToString(str.getBytes("utf-8"));
     12         } catch (Exception e) {
     13             throw new UnsupportedOperationException(e);
     14         }
     15     }
     16 
     17     /**
     18      * 编码64位
     19      *
     20      * @param str
     21      * @return
     22      */
     23     public static byte[] convertToBase64Byte(String str) {
     24         try {
     25             return BASE64_ENCODER.encode(str.getBytes("utf-8"));
     26         } catch (Exception e) {
     27             throw new UnsupportedOperationException(e);
     28         }
     29     }
     30 
     31     /**
     32      * 编码64位
     33      *
     34      * @param str
     35      * @return
     36      */
     37     public static String convertToBase64String(byte[] str) {
     38         return BASE64_ENCODER.encodeToString(str);
     39     }
     40 
     41     /**
     42      * 编码64位
     43      *
     44      * @param str
     45      * @return
     46      */
     47     public static byte[] convertToBase64Byte(byte[] str) {
     48         return BASE64_ENCODER.encode(str);
     49     }
     50 
     51     private static final Base64.Decoder Base64_DECODER = java.util.Base64.getDecoder();
     52 
     53     /**
     54      * 解码64位
     55      *
     56      * @param str
     57      * @return
     58      */
     59     public static byte[] convertFromBase64Byte(String str) {
     60         return Base64_DECODER.decode(str);
     61     }
     62 
     63     /**
     64      * 解码64位
     65      *
     66      * @param str
     67      * @return
     68      */
     69     public static String convertFromBase64(String str) {
     70         try {
     71             return new String(StringUtil.convertFromBase64Byte(str), "utf-8");
     72         } catch (Exception e) {
     73             throw new UnsupportedOperationException(e);
     74         }
     75     }
     76 
     77     /**
     78      * 解码64位
     79      *
     80      * @param str
     81      * @return
     82      */
     83     public static byte[] convertFromBase64Byte(byte[] str) {
     84         return Base64_DECODER.decode(str);
     85     }
     86 
     87     /**
     88      * 解码64位
     89      *
     90      * @param str
     91      * @return
     92      */
     93     public static String convertFromBase64(byte[] str) {
     94         try {
     95             return new String(convertFromBase64Byte(str), "utf-8");
     96         } catch (Exception e) {
     97             throw new UnsupportedOperationException(e);
     98         }
     99     }
    100 
    101     /**
    102      * ASE 对称加密
    103      *
    104      * @param str 需要加密的字符串
    105      * @param kk 对称加密顺序
    106      * @return
    107      */
    108     public static String convert_InBase64_ASE(String str, int... kk) {
    109         char[] strChars = convertToBase64String(str).toCharArray();
    110         return convert_ASE_ToCharString(strChars, kk);
    111     }
    112 
    113     /**
    114      * ASE 对称加密
    115      *
    116      * @param str 需要加密的字符串
    117      * @param kk 对称加密顺序
    118      * @return
    119      */
    120     public static String convert_UnBase64_ASE(String str, int... kk) {
    121         String convert_ASE = convert_ASE(str, kk);
    122         return convertFromBase64(convert_ASE);
    123     }
    124 
    125     /**
    126      * ASE 对称加密
    127      *
    128      * @param str 需要加密的字符串
    129      * @param kk 对称加密顺序
    130      * @return
    131      */
    132     public static String convert_ASE(String str, int... kk) {
    133         char[] strChars = str.toCharArray();
    134         return convert_ASE_ToCharString(strChars, kk);
    135     }
    136 
    137     /**
    138      * ASE 对称加密
    139      *
    140      * @param strChars 需要加密的字符串
    141      * @param kk 对称加密顺序
    142      * @return
    143      */
    144     public static String convert_ASE_ToCharString(char[] strChars, int... kk) {
    145         try {
    146             return new String(convert_ASE_ToChar(strChars, kk));
    147         } catch (Exception e) {
    148             throw new UnsupportedOperationException(e);
    149         }
    150     }
    151 
    152     /**
    153      * ASE 对称加密
    154      *
    155      * @param strChars 需要加密的字符串
    156      * @param kk 对称加密顺序
    157      * @return
    158      */
    159     public static char[] convert_ASE_ToChar(char[] strChars, int... kk) {
    160         /*二分对称性*/
    161         int fcount = strChars.length / 2;
    162         /*对称性 k 值*/
    163         for (int k : kk) {
    164             for (int i = 0; i < fcount; i += k) {
    165                 /*对称处理*/
    166                 char tmp = strChars[i];
    167                 strChars[i] = strChars[fcount + i];
    168                 strChars[fcount + i] = tmp;
    169             }
    170         }
    171         return strChars;
    172     }

    总结

    代码很简单,加密方式也很简单,也是起到加密作用,我们的秘钥 kk[] 的值,传入不一样,加密次数,和对称性也就不一样。除非知道你秘钥过程

    否则不可能解密;

    之所以使用最简单是方案,是因为考虑U3D的兼容性;

    代码在不同的手机,设备上,上的性能问题;

    U3D程序运行在手机设备上,字符处理也是比较消耗性能的;

  • 相关阅读:
    mysql innodb存储引擎和myisam引擎
    php 5.5 xhprof for windows
    sqlserver 2012 部署详解
    Oracle ASM 常用命令
    oracle 基础知识(十四)----索引扫描
    oracle 基础知识(十三)----执行计划
    Oracle DG --检查
    Oracle broker--详解
    初识正则表达式
    python中闭包和装饰器的理解(关于python中闭包和装饰器解释最好的文章)
  • 原文地址:https://www.cnblogs.com/shizuchengxuyuan/p/6728213.html
Copyright © 2011-2022 走看看