加密算法-對稱加密,支持解密;


前言

目前市面上的加密算法,有很多,什么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程序運行在手機設備上,字符處理也是比較消耗性能的;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM