加密算法-对称加密,支持解密;
前言
目前市面上的加密算法,有很多,什么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程序运行在手机设备上,字符处理也是比较消耗性能的;
跪求保留标示符 /** * @author: Troy.Chen(失足程序员, 15388152619) * @version: 2021-07-20 10:55 **/ C#版本代码 vs2010及以上工具可以 java 开发工具是netbeans 和 idea 版本,只有项目导入如果出现异常,请根据自己的工具调整 提供免费仓储。 最新的代码地址:↓↓↓ https://gitee.com/wuxindao 觉得我还可以,打赏一下吧,你的肯定是我努力的最大动力