欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

用Python实现CHAP_v2协议的加密与解密,借助Crypto库的便捷功能

最编程 2024-02-05 19:21:39
...
# coding = utf-8
from builtins import bytes

from Crypto.Hash import SHA1,SHA,MD4
from Crypto.Cipher import DES,ARC4

def GenerateNTResponse(AuthenticatorChallenge,PeerChalleng,UserName,password_unicode):
    PasswordHash=Nt_password_hash(password_unicode)
    Challenge=ChallengeHash(PeerChalleng,AuthenticatorChallenge,UserName)
    challenge_resposn=ChallengeResponse(PasswordHash,Challenge)
    return challenge_resposn

def ChallengeHash(PeerChalleng,AuthenticatorChallenge,UserName):
    Challenge=SHA1.new()
    Challenge.update(PeerChalleng)
    Challenge.update(AuthenticatorChallenge)
    Challenge.update(UserName)
    return Challenge.digest()[:8]
def Expand(rawkey):  #expand 7Bytes to 8 Bytes
    tmp_key = []
    for i in rawkey[:7]:
        tmp_key.append(i)
    key = []
    for i in range(8):
        key.append(b'\x00')
    # -------------------------
    key[0] = tmp_key[0]
    for i in range(1, 7):
        key[i] = ((tmp_key[i - 1] << (8 - i)) & 0xff) | (tmp_key[i] >> i)
    key[7] =  (tmp_key[6] << 1) & 0xff
    global b
    for i in range(len(key)):
        b = 1
        for j in range(1, 8):
            t = (key[i] >> j)
            b = (t ^ b) & 0x1 #
        key[i] = (key[i] & 0xfe) | b
    ans = b''
    for i in range(8):
        ans += bytes([key[i]])
    return ans
def ChallengeResponse(PasswordHash,Challenge):
    zero = b'\x00'
    while(len(PasswordHash) < 21): # important
        PasswordHash += zero #zero-padded to 21 octets
    res = DES.new(Expand(PasswordHash[0:7]), DES.MODE_ECB).encrypt(Challenge)
    res += DES.new(Expand(PasswordHash[7:14]), DES.MODE_ECB).encrypt(Challenge)
    res += DES.new(Expand(PasswordHash[14:21]), DES.MODE_ECB).encrypt(Challenge)
    return res
def Nt_password_hash(Password):
    PasswordHash=MD4.new(Password)
    return PasswordHash.digest()

def Nt_password_hashhash(Passwordhash):
    PasswordHashhash=MD4.new(Passwordhash)
    return PasswordHashhash.digest()

def GetMasterKey(PasswordHashhash,NTResponse):
    Magic1 =b'\x54\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x4d\x50\x50\x45\x20\x4d\x61\x73\x74\x65\x72\x20\x4b\x65\x79'
    MasterKey = SHA.new()
    MasterKey.update(PasswordHashhash)
    MasterKey.update(NTResponse)
    MasterKey.update(Magic1)
    return MasterKey.digest()[:16]

def GetAsymmetricStartKey(MasterKey,IsSend,IsServer):
    Shapad1=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    Shapad2=b'\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2'
    Magic2 = b'\x4f\x6e\x20\x74\x68\x65\x20\x63\x6c\x69\x65\x6e\x74\x20\x73\x69\x64\x65\x2c\x20\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x73\x65\x6e\x64\x20\x6b\x65\x79\x3b\x20\x6f\x6e\x20\x74\x68\x65\x20\x73\x65\x72\x76\x65\x72\x20\x73\x69\x64\x65\x2c\x20\x69\x74\x20\x69\x73\x20\x74\x68\x65\x20\x72\x65\x63\x65\x69\x76\x65\x20\x6b\x65\x79\x2e'
    Magic3 = b'\x4f\x6e\x20\x74\x68\x65\x20\x63\x6c\x69\x65\x6e\x74\x20\x73\x69\x64\x65\x2c\x20\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x72\x65\x63\x65\x69\x76\x65\x20\x6b\x65\x79\x3b\x20\x6f\x6e\x20\x74\x68\x65\x20\x73\x65\x72\x76\x65\x72\x20\x73\x69\x64\x65\x2c\x20\x69\x74\x20\x69\x73\x20\x74\x68\x65\x20\x73\x65\x6e\x64\x20\x6b\x65\x79\x2e'
    s=b''
    if IsSend:
        if IsServer:
            s+=Magic3
        else:
            s+=Magic2
    else:
        if IsServer:
            s+=Magic2
        else:
            s+=Magic3
    SessionKey = SHA.new()
    SessionKey.update(MasterKey)
    SessionKey.update(Shapad1)
    SessionKey.update(s)
    SessionKey.update(Shapad2)
    return SessionKey.digest()[:16]

def GetNewKeyFromSHA(StartKey, SessionKey):
    Shapad1=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    Shapad2=b'\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2\xf2'
    InterimKey = SHA.new()
    InterimKey.update(StartKey)
    InterimKey.update(Shapad1)
    InterimKey.update(SessionKey)
    InterimKey.update(Shapad2)
    return InterimKey.digest()[:16]

def RC4_encrypto(data,key):
    rc41 = ARC4.new(key)
    encrypted = rc41.encrypt(data)
    return encrypted
def RC4_decrypto(data,key):
    rc41=ARC4.new(key)
    return rc41.decrypt(data)
def print_hex(s):
    for i in s:
        print('\%#x' % i, end='')
    print('')

if __name__ == "__main__":

    UserName = '2032017012'.encode("utf8")
    password = '2032017012'.encode("utf8")
    AuthenticatorChallenge = b'\x2C\x64\x5B\xC3\xAD\xBB\xDB\xD8\x72\x68\x21\x74\x25\x56\xCE\x11'

    PeerChalleng = b'\xFC\xE6\x96\x83\xE1\x92\x1C\x26\xEE\xF6\x7A\xE6\xC5\x9E\x24\x9E'

    password_unicode = b''
    for ch in password:
        password_unicode += bytes([ch])
        password_unicode +=b'\x00'
    NTResponse=GenerateNTResponse(AuthenticatorChallenge, PeerChalleng, UserName, password_unicode)
    print("挑战响应值:")
    print_hex(NTResponse)
    PasswordHashhash = Nt_password_hashhash(Nt_password_hash(password_unicode))
    print("PasswordHashhash")
    print_hex(PasswordHashhash)
    Master_Key=GetMasterKey(PasswordHashhash,NTResponse)
    print("MasterKey:")
    print_hex(Master_Key)
    MasterSendKey=GetAsymmetricStartKey(Master_Key,True,True)
    print("MasterSendKey:")
    print_hex(MasterSendKey)
    MasterReceiveKey = GetAsymmetricStartKey(Master_Key,False, True)
    print("MasterReceiveKey:")
    print_hex(MasterReceiveKey)
    SendSessionKey=GetNewKeyFromSHA(MasterSendKey,MasterSendKey)
    ReceiveSessionKey=GetNewKeyFromSHA(MasterReceiveKey,MasterReceiveKey)
    print("sendSessionKey:")
    print_hex(SendSessionKey)
    print("ReceiveSessionKey:")
    print_hex(ReceiveSessionKey)
    Rawcontext="测试数据:我爱学网络密码,网络密码使我快乐"
    print("Rawcontext:"+Rawcontext)
    Sendtext=RC4_encrypto(Rawcontext.encode("utf8"),SendSessionKey)
    print("Sendtext:")
    print_hex(Sendtext)
    Decrptotext=RC4_decrypto(Sendtext,SendSessionKey)
    print("Decrptotext:")
    print(Decrptotext.decode('utf-8'))
    DatatoDecrpto=b'\xfd\x90'\
                    b'\x00\x29\x0f\x04\x22\x8b\x01\x18\x61\xbb\xfd\x44\xa5\xf6\x15\x80'\
                    b'\xd8\x3e\xe1\x57\xc7\x6b\x1f\x71\x03\x30\xbf\xe0\xbf\x38\xd9\x95'\
                    b'\xab\x01\x29\x9b\x4a\xdd\xb2\x95\x0d\x6b\xc1\x98\x54\xc0\x75\xba'\
                    b'\x4d\x31\x59\xe4\x78\xf7\xe8\x25\x66\x72\xd2\x7c\x9b\x98\x56\x29'\
                    b'\x32\xee\x09\x38\x18\xa2\xbe\x3e\xeb\x83\xd1\xcb\xb8\x72\x54\xaf'\
                    b'\x2c\x0c\x0a\xbf\x57\x3f\xf6\xe2\xa3\x80\x93\x36\xb6\x78\x31\x6d'\
                    b'\x7b\x1f\x68'
    Decrptotext2=RC4_decrypto(DatatoDecrpto,SendSessionKey)
    print("Decrptotext2:")
    print_hex(Decrptotext2)
    print(Decrptotext2.decode('utf-8'))

测试数据加解密成功!

对数据包通信数据进行解密:

原文地址:https://www.cnblogs.com/xubuji/p/12924311.html