`
hereson2
  • 浏览: 466371 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

hoxede的QQ填充算法和TEA 加解密的python实现

阅读更多
"""

The MIT License



Copyright (c) 2005 hoxide



Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:



The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.



THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.





QQ Crypt module.



"""



from struct import pack as _pack

from struct import unpack as _unpack

from binascii import b2a_hex, a2b_hex



from random import seed

from random import randint as _randint



__all__ = ['encrypt', 'decrypt']



seed()



op = 0xffffffffL





def xor(a, b):

    a1,a2 = _unpack('>;LL', a[0:8])

    b1,b2 = _unpack('>;LL', b[0:8])

    r = _pack('>;LL', ( a1 ^ b1) & op, ( a2 ^ b2) & op)

    return r





def code(v, k):

    """

    TEA coder encrypt 64 bits value, by 128 bits key,

    QQ do 16 round TEA.

    To see:

    http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html .

   

    TEA 加密,  64比特明码, 128比特密钥, qq的TEA算法使用16轮迭代

    具体参看

    http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html



    >;>;>; c = code('abcdefgh', 'aaaabbbbccccdddd')

    >;>;>; b2a_hex(c)

    'a557272c538d3e96'

    """

    n=16  #qq use 16

    delta = 0x9e3779b9L

    k = _unpack('>;LLLL', k[0:16])

    y, z = _unpack('>;LL', v[0:8])

    s = 0

    for i in xrange(n):

        s += delta

        y += (op &(z<<4))+ k[0] ^ z+ s ^ (op&(z>;>;5)) + k[1] ;

        y &= op

        z += (op &(y<<4))+ k[2] ^ y+ s ^ (op&(y>;>;5)) + k[3] ;

        z &= op

    r = _pack('>;LL',y,z)

    return r



def encrypt(v, k):

    """

    Encrypt Message follow QQ's rule.

    用QQ的规则加密消息



    v is the message to encrypt, k is the key

    参数 v 是被加密的明文, k是密钥

    fill char is some random numbers (in old QQ is 0xAD)

    填充字符数是随机数, (老的QQ使用0xAD)

    fill n char's n = (8 - (len(v)+2)) %8 + 2

    填充字符的个数 n = (8 - (len(v)+2)) %8 + 2

    ( obviously, n is 2 at least, n is 2-9)

    ( 显然, n至少为2, 取2到9之间)



    then insert (n - 2)|0xF8 in the front of the fill chars

    然后在填充字符前部插入1字节, 值为 ((n - 2)|0xF8)

    to record the number of fill chars.

    以便标记填充字符的个数.

    append 7 '\0' in the end of the message.

    在消息尾部添加7字节'\0'

   

    thus the lenght of the message become filln + 8 + len(v),

    因此消息总长变为 filln + 8 + len(v),

    and it == 0 (mod

    他模8余0(被8整除)



    Encrypt the message .

    加密这段消息

    Per 8 bytes,

    每8字节,

    the result is:

    规则是

   

    r = code( v ^ tr, key) ^ to   (*)



    code is the QQ's TEA function.

    code函数就是QQ 的TEA加密函数.

    v is 8 bytes data to encrypt.

    v是被加密的8字节数据

    tr is the result in preceding round.

    tr是前次加密的结果

    to is the data coded in perceding round, is v_pre ^ r_pre_pre

    to是前次被加密的数据, 等于 v_pre ^ r_pre_pre



    For the first 8 bytes 'tr' and 'to' is zero.

    对头8字节, 'tr' 和 'to' 设为零

   

    loop and loop,

    不断循环,

    that's end.

    结束.

   

    >;>;>; en = encrypt('', b2a_hex('b537a06cf3bcb33206237d7149c27bc3'))

    >;>;>; decrypt(en,  b2a_hex('b537a06cf3bcb33206237d7149c27bc3'))

    ''

    """

    ##FILL_CHAR = chr(0xAD)

    END_CHAR = '\0'

    FILL_N_OR = 0xF8

    vl = len(v)

    filln = (8-(vl+2))%8 + 2;

    fills = ''

    for i in xrange(filln):

        fills = fills + chr(_randint(0, 0xff))

    v = ( chr((filln -2)|FILL_N_OR)

          + fills

          + v

          + END_CHAR * 7)

    tr = '\0'*8

    to = '\0'*8

    r = ''

    o = '\0' * 8

    #print 'len(v)=', len(v)

    for i in xrange(0, len(v),:

        o = xor(v[i:i+8], tr)

        tr = xor( code(o, k), to)

        to = o

        r += tr

    return r



def decrypt(v, k):

    """

    DeCrypt Message

    消息解密

   

    by (*) we can find out follow easyly:

    通过(*)式,我们可以容易得发现(明文等于):

   

    x  = decipher(v[i:i+8] ^ prePlain, key) ^ preCyrpt

   

    prePlain is pre 8 byte to be code.

    perPlain 是被加密的前8字节

   

    Attention! It's v per 8 byte value xor pre 8 byte prePlain,

    注意! 他等于前8字节数据异或上前8字节prePlain,

    not just per 8 byte.

    而不只是前8字节.

    preCrypt is pre 8 byte Cryped.

    perCrypt 是前8字节加密结果.



    In the end of deCrypte the raw message,

    在解密完原始数据后,

    we have to cut the filled bytes which was append in encrypt.

    我们必须去除在加密是添加的填充字节.



    the number of the filling bytes in the front of message is

    填充在消息头部的字节数是

    pos + 1.

   

    pos is the first byte of deCrypted --- r[0] & 0x07 + 2

    pos等于解密后的第一字节 --- r[0] & 0x07 + 2



    the end of filling aways is 7 zeros.

    尾部填充始终是7字节零.

    we can test the of 7 bytes is zeros, to make sure it is right.

    我们可以通测试最后7字节是零, 来确定它是正确的.

   

    so return r[pos+1:-7]

    所以返回 r[pos+1:-7]



    >;>;>; r = encrypt('', b2a_hex('b537a06cf3bcb33206237d7149c27bc3'))

    >;>;>; decrypt(r, b2a_hex('b537a06cf3bcb33206237d7149c27bc3'))

    ''

    >;>;>; r = encrypt('abcdefghijklimabcdefghijklmn', b2a_hex('b537a06cf3bcb33206237d7149c27bc3'))

    >;>;>; decrypt(r, b2a_hex('b537a06cf3bcb33206237d7149c27bc3'))

    'abcdefghijklimabcdefghijklmn'

    >;>;>; import md5

    >;>;>; key = md5.new(md5.new('python').digest()).digest()

    >;>;>; data='8CE160B9F312AEC9AC8D8AEAB41A319EDF51FB4BB5E33820C77C48DFC53E2A48CD1C24B29490329D2285897A32E7B32E9830DC2D0695802EB1D9890A0223D0E36C35B24732CE12D06403975B0BC1280EA32B3EE98EAB858C40670C9E1A376AE6C7DCFADD4D45C1081571D2AF3D0F41B73BDC915C3AE542AF2C8B1364614861FC7272E33D90FA012620C18ABF76BE0B9EC0D24017C0C073C469B4376C7C08AA30'

    >;>;>; data = a2b_hex(data)

    >;>;>; b2a_hex(decrypt(data, key))

    '00553361637347436654695a354d7a51531c69f1f5dde81c4332097f0000011f4042c89732030aa4d290f9f941891ae3670bb9c21053397d05f35425c7bf80000000001f40da558a481f40000100004dc573dd2af3b28b6a13e8fa72ea138cd13aa145b0e62554fe8df4b11662a794000000000000000000000000dde81c4342c8966642c4df9142c3a4a9000a000a'

   

    """

    l = len(v)

    #if l%8 !=0 or l<16:

    #    return ''

    prePlain = decipher(v, k)

    pos = (ord(prePlain[0]) & 0x07L) +2

    r = prePlain

    preCrypt = v[0:8]

    for i in xrange(8, l,:

        x = xor(decipher(xor(v[i:i+8], prePlain),k ), preCrypt)

        prePlain = xor(x, preCrypt)

        preCrypt = v[i:i+8]

        r += x

    if r[-7:] != '\0'*7: return None

   



    return r[pos+1:-7]



def decipher(v, k):

    """

    TEA decipher, decrypt  64bits value with 128 bits key.

    TEA 解密程序, 用128比特密钥, 解密64比特值



    it's the inverse function of TEA encrypt.

    他是TEA加密函数的反函数.



    >;>;>; c = code('abcdefgh', 'aaaabbbbccccdddd')

    >;>;>; decipher( c, 'aaaabbbbccccdddd')

    'abcdefgh'

    """



    n = 16

    y, z = _unpack('>;LL', v[0:8])

    a, b, c, d = _unpack('>;LLLL', k[0:16])

    delta = 0x9E3779B9L;

    s = (delta << 4)&op

    for i in xrange(n):

        z -= ((y<<4)+c) ^ (y+s) ^ ((y>;>;5) + d)

        z &= op

        y -= ((z<<4)+a) ^ (z+s) ^ ((z>;>;5) + b)

        y &= op

        s -= delta

        s &= op

    return _pack('>;LL', y, z)



def _test():

    import doctest, tea

    return doctest.testmod(tea)





if __name__ == "__main__":

    _test()
分享到:
评论

相关推荐

    QQ-TEA加解密代码

    6. 分析QQ报文特征和协议:为了实现QQ-TEA加解密,开发者需要了解QQ的网络通信协议。这涉及到分析网络抓包数据,识别出用于传输聊天记录的特定数据包格式,以及这些数据包如何与QQ-TEA加密相结合。 7. 实现细节:在...

    ios开发Tea加密解密

    本教程将深入讲解如何在iOS应用中实现Tea加密解密,以及如何正确地存储和恢复加密数据。 Tea加密算法基于两个32位的整数,它使用了四轮非线性变换,通过多次加法、乘法和位移操作来实现数据的加密。Tea算法的特点是...

    易语言TEA加密解密源码.7z

    8. **溢出处理**:由于易语言和TEA算法中的运算可能涉及32位整数的溢出,因此在实现时需要注意处理溢出情况,以确保正确性。 9. **性能优化**:易语言提供了高效的数据处理能力,合理利用这些特性可以提高加密解密...

    密码学实验之流密码算法:A5算法与RC4算法加密流程和python代码实现

    在Python中实现这两种算法,可以方便地进行加密和解密操作。例如,对于A5算法,用户需要输入LFSR的初始状态,程序会检查输入是否符合二进制规则。对于RC4,需要初始化状态向量,扩展密钥并生成密钥流,然后对明文...

    QQ加密解密1.5易语言源码

    源码中实现的TEA加解密部分,可以帮助开发者理解这种古老的加密算法的工作原理。 2. MD5计算: MD5是广泛使用的哈希函数,它将任意长度的数据转化为固定长度的128位(16字节)摘要。尽管MD5在安全性方面已不再可靠...

    QQTEA算法源码.rar

    QQTEA算法的核心思想是通过一系列的位操作(如XOR、加法、移位等)来实现数据的加密和解密。它使用64轮迭代过程,每轮迭代都对64位的数据块进行操作。相比TEA的32轮,QQTEA的64轮提供了更高的安全级别。 以下是QQ...

    QT实现多边形填充算法

    通过处理鼠标事件、存储顶点、判断点在多边形内以及使用`QPainter`进行绘制,可以创建出交互式的图形界面,允许用户动态地绘制和填充多边形。在实际应用中,开发者还可以根据需求添加更多的功能,如选择不同颜色、...

    数据的加密传输——单片机上实现TEA加密解密算法.pdf

    TEA算法是一种简单的高速加密算法,其特点是加密和解密速度快,实现简单。TEA算法处理的数据块大小为64位(8字节),使用128位(16字节)的密钥。标准的TEA算法执行64轮迭代,但最少可执行32轮。虽然现在有些系统...

    社区发现算法 加权GN算法的Python实现

    传统的GN算法只适用于无向无权图的社区发现,通过对边介数进行调整得到无向有权图的GN算法实现

    智能驾驶算法python实现

    智能驾驶算法是现代汽车工业与信息技术的交叉领域,它利用高级的计算机视觉、机器学习、控制理论等技术,实现车辆的自主...通过不断学习和实践,开发者可以利用Python实现复杂的智能驾驶算法,推动自动驾驶技术的发展。

    C语言实现的QQ TEA 加解密.zip

    总的来说,C语言实现QQ TEA加密算法需要理解算法原理,正确地进行位操作,并注意内存安全和性能优化。在实际项目中,我们还需要考虑与其他系统集成、加密模式(如ECB、CBC等)、填充方式等因素,以适应不同的安全...

    des加密算法实现任意文件加解密

    2. **初始化 Cipher 对象**:使用`Cipher`类的`getInstance()`方法获取一个DES加密/解密对象,并设置其工作模式(如ECB、CBC等)和填充模式(如NoPadding、PKCS5Padding等)。 3. **加密操作**:调用`Cipher`对象的`...

    易语言QQTEA算法源码

    QQTEA(Quick and Tiny Encryption Algorithm)是一种简单的对称加密算法,由David Wheeler和Roger Needham在1994年提出。它不是一种现代复杂的加密标准,如AES,但因其小巧且快速的特点,在某些特定场景下仍有一定...

    TEA_example_CPP.rar_TEA算法_tea_tea c_tea 加密_tea加密

    TEA(Tiny Encryption Algorithm) 是一种简单高效的加密算法,以加密解密速度快,实现简单著称。算法真的很简单,TEA算法每一次可以操作64-bit(8-byte),采用128-bit(16-byte)作为key,算法采用迭代的形式,推荐的...

    用 Python 重写 PHP 加密解密算法 authcode

    5. **截取与填充**:根据需要,可能对加密后的字符串进行截取和填充,确保输出长度的固定性。 6. **Base64编码**:将处理后的字符串转化为Base64编码,使得结果更易于在网络上传输和存储。 在Python中实现`authcode...

    c++代码实现tea加密算法的实例详解

    TEA加密算法的核心在于其加密过程,由`tea_encrypt`和`tea_decrypt`两个函数实现。这两个函数分别用于加密和解密,它们接受两个32位无符号整数(v0和v1)作为输入,以及四个32位密钥(k0, k1, k2, k3)。加密过程中...

    计算机图形学的区域填充算法

    根据提供的信息,我们可以深入探讨...边缘表算法作为一种有效的区域填充方法,通过构建边缘表和活动边缘表来简化填充过程,提高了渲染效率。理解这些算法的实现原理有助于更好地掌握计算机图形学的核心概念和技术。

    JPEG图像压缩算法的python实现

    在研究JPEG压缩编码对图像数据压缩的基本原理的基础上,设计了JPEG图像压缩算法程序实现流程,利用 Python语言对程序进行了编写,并实现了对压缩质量进行控制,验证了JPEG压缩编码对图像数据压缩的可行性。

    python实现扫码验证,调用qq的api

    本项目专注于使用Python来实现扫码验证功能,同时调用QQ的API接口,进行身份校验。这一过程涉及到多个技术点,下面将逐一进行详细阐述。 首先,Python扫码验证的核心是二维码读取与解析。Python中有许多库可以支持...

    利用Python实现遗传算法求函数最值

    遗传算法以一种群体中的所有个体为对象,并利用随机化...参数编码、初始群体的设定、适应度函数的设计、遗传操作设计、控制参数设定五个要素组成了遗传算法的核心内容,此程序利用Python实现遗传算法求函数最值问题。

Global site tag (gtag.js) - Google Analytics