QQ协议TEA加密解密代码 C#
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                QQ协议TEA加密解密代码 C#
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                ???? 網上找到的qq協議的TEA加密和解密說明如下: 也有很多源代碼,但是感覺上代碼比較復雜,不容易看。我用C#重寫了下。 基于2008協議
???? * QQ消息的加密算法是一個16次的迭代過程,并且是反饋的,每一個加密單元是8字節,輸出也是8字節,密鑰是16字節
???? * 我們以prePlain表示前一個明文塊,plain表示當前明文塊,crypt表示當前明文塊加密得到的密文塊,preCrypt表示前一個密文塊???? * f表示加密算法,d表示解密算法 那么從plain得到crypt的過程是:
???? *?????? crypt = f(plain ^ preCrypt) ^ prePlain
???? * 所以,從crypt得到plain的過程自然是
???? *?????? plain = d(crypt ^ prePlain) ^ preCrypt
???? * 此外,算法有它的填充機制,其會在明文前和明文后分別填充一定的字節數,以保證明文長度是8字節的倍數
???? * 填充的字節數與原始明文長度有關,填充的方法是:
???? *
???? *????? ------- 消息填充算法 -----------
???? *????? a = (明文長度 + 10) mod 8
???? *????? if(a 不等于 0) a = 8 - a;
???? *????? b = 隨機數 & 0xF8 | a;????????????? 這個的作用是把a的值保存了下來
???? *????? plain[0] = b;?????????????????? 然后把b做為明文的第0個字節,這樣第0個字節就保存了a的信息,這個信息在解密時就要用來找到真正明文的起始位置
???? *????? plain[1 至 a+2] = 隨機數 & 0xFF;??? 這里用隨機數填充明文的第1到第a+2個字節
???? *????? plain[a+3 至 a+3+明文長度-1] = 明文; 從a+3字節開始才是真正的明文
???? *????? plain[a+3+明文長度, 最后] = 0;?????? 在最后,填充0,填充到總長度為8的整數為止。到此為止,結束了,這就是最后得到的要加密的明文內容
???? *????? ------- 消息填充算法 ------------
?
Code??1????/**////?<summary>
??2????///?加密解密QQ消息包的工具類.?
??3????///?</summary>
??4????public?static?class?QQCrypter
??5????{
??6????????private?static?void?code(byte[]?In,?int?inOffset,?int?inPos,?byte[]?Out,?int?outOffset,?int?outPos,?byte[]?key)
??7????????{
??8????????????if?(outPos?>?0)
??9????????????{
?10????????????????for?(int?i?=?0;?i?<?8;?i++)
?11????????????????{
?12????????????????????In[outOffset?+?outPos?+?i]?=?(byte)(In[inOffset?+?inPos?+?i]?^?Out[outOffset?+?outPos?+?i?-?8]);
?13????????????????}
?14????????????}
?15????????????uint[]?formattedKey?=?FormatKey(key);
?16????????????uint?y?=?ConvertByteArrayToUInt(In,?outOffset?+?outPos);
?17????????????uint?z?=?ConvertByteArrayToUInt(In,?outOffset?+?outPos?+?4);
?18????????????uint?sum?=?0;
?19????????????uint?delta?=?0x9e3779b9;
?20????????????uint?n?=?16;
?21
?22????????????while?(n--?>?0)
?23????????????{
?24????????????????sum?+=?delta;
?25????????????????y?+=?((z?<<?4)?+?formattedKey[0])?^?(z?+?sum)?^?((z?>>?5)?+?formattedKey[1]);
?26????????????????z?+=?((y?<<?4)?+?formattedKey[2])?^?(y?+?sum)?^?((y?>>?5)?+?formattedKey[3]);
?27????????????}
?28????????????Array.Copy(ConvertUIntToByteArray(y),?0,?Out,?outOffset?+?outPos,?4);
?29????????????Array.Copy(ConvertUIntToByteArray(z),?0,?Out,?outOffset?+?outPos?+?4,?4);
?30????????????if?(inPos?>?0)
?31????????????{
?32????????????????for?(int?i?=?0;?i?<?8;?i++)
?33????????????????{
?34????????????????????Out[outOffset?+?outPos?+?i]?=?(byte)(Out[outOffset?+?outPos?+?i]?^?In[inOffset?+?inPos?+?i?-?8]);
?35????????????????}
?36????????????}
?37????????}
?38
?39????????private?static?void?decode(byte[]?In,?int?inOffset,?int?inPos,?byte[]?Out,?int?outOffset,?int?outPos,?byte[]?key)
?40????????{
?41????????????if?(outPos?>?0)
?42????????????{
?43????????????????for?(int?i?=?0;?i?<?8;?i++)
?44????????????????{
?45????????????????????Out[outOffset?+?outPos?+?i]?=?(byte)(In[inOffset?+?inPos?+?i]?^?Out[outOffset?+?outPos?+?i?-?8]);
?46????????????????}
?47????????????}
?48????????????else
?49????????????{
?50????????????????Array.Copy(In,?inOffset,?Out,?outOffset,?8);
?51????????????}
?52????????????uint[]?formattedKey?=?FormatKey(key);
?53????????????uint?y?=?ConvertByteArrayToUInt(Out,?outOffset?+?outPos);
?54????????????uint?z?=?ConvertByteArrayToUInt(Out,?outOffset?+?outPos?+?4);
?55????????????uint?sum?=?0xE3779B90;
?56????????????uint?delta?=?0x9e3779b9;
?57????????????uint?n?=?16;
?58
?59????????????while?(n--?>?0)
?60????????????{
?61????????????????z?-=?((y?<<?4)?+?formattedKey[2])?^?(y?+?sum)?^?((y?>>?5)?+?formattedKey[3]);
?62????????????????y?-=?((z?<<?4)?+?formattedKey[0])?^?(z?+?sum)?^?((z?>>?5)?+?formattedKey[1]);
?63????????????????sum?-=?delta;
?64????????????}
?65????????????Array.Copy(ConvertUIntToByteArray(y),?0,?Out,?outOffset?+?outPos,?4);
?66????????????Array.Copy(ConvertUIntToByteArray(z),?0,?Out,?outOffset?+?outPos?+?4,?4);
?67????????}
?68
?69????????/**////?<summary>
?70????????///?解密
?71????????///?</summary>
?72????????///?<param?name="In">密文</param>
?73????????///?<param?name="offset">密文開始的位置</param>
?74????????///?<param?name="len">密文長度</param>
?75????????///?<param?name="key">密鑰</param>
?76????????///?<returns>返回明文</returns>
?77????????public?static?byte[]?Decrypt(byte[]?In,?int?offset,?int?len,?byte[]?key)
?78????????{
?79????????????//?因為QQ消息加密之后至少是16字節,并且肯定是8的倍數,這里檢查這種情況
?80????????????if?((len?%?8?!=?0)?||?(len?<?16))
?81????????????{
?82????????????????return?null;
?83????????????}
?84????????????byte[]?Out?=?new?byte[len];
?85????????????for?(int?i?=?0;?i?<?len;?i?+=?8)
?86????????????{
?87????????????????decode(In,?offset,?i,?Out,?0,?i,?key);
?88????????????}
?89????????????for?(int?i?=?8;?i?<?len;?i++)
?90????????????{
?91????????????????Out[i]?=?(byte)(Out[i]?^?In[offset?+?i?-?8]);
?92????????????}
?93????????????int?pos?=?Out[0]?&?0x07;
?94????????????len?=?len?-?pos?-?10;
?95????????????byte[]?res?=?new?byte[len];
?96????????????Array.Copy(Out,?pos?+?3,?res,?0,?len);
?97????????????return?res;
?98????????}
?99
100????????public?static?byte[]?Encrypt(byte[]?In,?int?offset,?int?len,?byte[]?key)
101????????{
102????????????//?計算頭部填充字節數
103????????????int?pos?=?(len?+?10)?%?8;
104????????????if?(pos?!=?0)
105????????????{
106????????????????pos?=?8?-?pos;
107????????????}
108????????????byte[]?plain?=?new?byte[len?+?pos?+?10];
109????????????plain[0]?=?(byte)((Rnd.Next()?&?0xF8)?|?pos);
110????????????for?(int?i?=?1;?i?<?pos?+?3;?i++)
111????????????{
112????????????????plain[i]?=?(byte)(Rnd.Next()?&?0xFF);
113????????????}
114????????????Array.Copy(In,?0,?plain,?pos?+?3,?len);
115????????????for?(int?i?=?pos?+?3?+?len;?i?<?plain.Length;?i++)
116????????????{
117????????????????plain[i]?=?0x0;
118????????????}
119????????????//?定義輸出流
120????????????byte[]?outer?=?new?byte[len?+?pos?+?10];
121????????????for?(int?i?=?0;?i?<?outer.Length;?i?+=?8)
122????????????{
123????????????????code(plain,?0,?i,?outer,?0,?i,?key);
124????????????}
125????????????return?outer;
126????????}
127
128????????private?static?uint[]?FormatKey(byte[]?key)
129????????{
130????????????if?(key.Length?==?0)
131????????????{
132????????????????throw?new?ArgumentException("Key?must?be?between?1?and?16?characters?in?length");
133????????????}
134????????????byte[]?refineKey?=?new?byte[16];
135????????????if?(key.Length?<?16)
136????????????{
137????????????????Array.Copy(key,?0,?refineKey,?0,?key.Length);
138????????????????for?(int?k?=?key.Length;?k?<?16;?k++)
139????????????????{
140????????????????????refineKey[k]?=?0x20;
141????????????????}
142????????????}
143????????????else
144????????????{
145????????????????Array.Copy(key,?0,?refineKey,?0,?16);
146????????????}
147????????????uint[]?formattedKey?=?new?uint[4];
148????????????int?j?=?0;
149????????????for?(int?i?=?0;?i?<?refineKey.Length;?i?+=?4)
150????????????{
151????????????????formattedKey[j++]?=?ConvertByteArrayToUInt(refineKey,?i);
152????????????}
153????????????return?formattedKey;
154????????}
155
156????????private?static?byte[]?ConvertUIntToByteArray(uint?v)
157????????{
158????????????byte[]?result?=?new?byte[4];
159????????????result[0]?=?(byte)((v?>>?24)?&?0xFF);
160????????????result[1]?=?(byte)((v?>>?16)?&?0xFF);
161????????????result[2]?=?(byte)((v?>>?8)?&?0xFF);
162????????????result[3]?=?(byte)((v?>>?0)?&?0xFF);
163????????????return?result;
164????????}
165
166????????private?static?uint?ConvertByteArrayToUInt(byte[]?v,?int?offset)
167????????{
168????????????if?(offset?+?4?>?v.Length)
169????????????{
170????????????????return?0;
171????????????}
172????????????uint?output;
173????????????output?=?(uint)(v[offset]?<<?24);
174????????????output?|=?(uint)(v[offset?+?1]?<<?16);
175????????????output?|=?(uint)(v[offset?+?2]?<<?8);
176????????????output?|=?(uint)(v[offset?+?3]?<<?0);
177????????????return?output;
178????????}
179
180????}
181
?
轉載于:https://www.cnblogs.com/beikx/archive/2009/11/08/1598309.html
總結
以上是生活随笔為你收集整理的QQ协议TEA加密解密代码 C#的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 离职后祝福同事的话语 祝离职同事前程似锦
 - 下一篇: FileUpload路径