-2

所以在我现在正在处理的代码中,有一个部分使用 md5 生成本地密钥。生成字符串的代码如下:

data_encoded = serialize(results)
data_encoded = data_encoded.encode('base64')
thishex = md5(str(checkdate)+licensing_secret_key)
thishash = thishex.hexdigest()
data_encoded = thishash+data_encoded
data_encoded = data_encoded[::-1]
thathex = md5(data_encoded+licensing_secret_key)
thathash = thathex.hexdigest()
data_encoded = data_encoded+ thathash
data_encoded = textwrap.fill(data_encoded,70)
results["localkey"] = data_encoded
print data_encoded

whereresults是包含值的字典,checkdate是 time.time() 的结果。

现在我尝试解密如下:

tmp = len(localkey) - 32
localdata = localkey[:tmp]
md5hash = localkey[tmp:]
localtemphex = md5(localdata+licensing_secret_key)
localtemphash = localtemphex.hexdigest()
print md5hash
print localtemphash

其中localkey是之前生成的字符串 ( results["localkey"] = data_encoded),licensing_secret_key 是开头给出的字符串。

print 命令显示不匹配的字符串。我在这里有什么遗漏吗?

提前致谢

编辑

根据评论,这里有更多关于我想要实现的目标的信息。假设有人购买了许可证密钥 - 每次他/她使用产品时,脚本都会尝试对服务器进行身份验证以检查许可证的有效性。现在,由于某种原因,如果无法轮询服务器,则需要一种机制,其中存在一个有效的本地密钥(在上次远程检查时生成并存储在本地),例如一些日子。

因此,代码本质上是在尝试检查最后生成的本地密钥是否有效。除了可能反转哈希之外,我不知道如何检查它,现在我知道(从评论中)这是不可能的。(本质上,我试图模拟 WHMCS 的许可证检查器附加组件之后的模型)

(PS:对不起,如果这听起来太无聊了——只是掌握了一般的编码技巧,特别是 Python)。

4

2 回答 2

3

试试这个脚本。我估计运行需要半秒*

__all__ = ('brute_force', 'crack', 'make_library')
encryptions = ['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512']

import hashlib
from random import randint
from os import _exit, mkdir
from sys import stdout, argv
from atexit import register
from time import sleep
from os import fsync, rename

class brute_force:
    def __init__(self, mot_de_passe_a_trouver='', nombre_de_carateres_depart = 1, caracteres_max=42):
        '''
        Librairie de recherche de mots de passes encrypte
        Library for decrypting encrypted passwords

        Encryptions:
        md5, sha1, sha224, sha256, sha384, sha512
        '''
        self.ascii_debut = 32
        self.ascii_fin = 126
        self.nombre_de_mots = 0
        self.compteur = 1
        self.puissances = []
        self.dernier_mot_de_passe_hashe = ''
        self.dernier_mot_de_passe = ''
        self.nombre_de_carateres = nombre_de_carateres_depart
        self.mot_de_passe_a_trouver = mot_de_passe_a_trouver

        while (self.compteur <= caracteres_max):
            self.puissances.append(int(((self.ascii_fin-self.ascii_debut)**(self.compteur))*2.5))#you could change the "2.5" but you risk fail many words if you reduce it and if you increment it you will waste time
            self.compteur += 1
        self.compteur = 1

    def __len__(self):
        return self.nombre_de_mots

    def set_char(self, nombre_de_caracteres=int()):
        '''a shortcut to change number of chars by generated words'''
        if not nombre_de_caracteres:
            self.nombre_de_carateres = nombre_de_caracteres
        return self.nombre_de_carateres

    def one_search(self, encryption):
        '''Generate one random password and returns true if found'''
        self.new()
        self.encode(encryption)
        if (self.mot_de_passe_a_trouver == self.dernier_mot_de_passe_hashe):
            return True
        return False

    def new(self):
        '''
        Creer un mot de passe possible
        Create a new random word
        '''
        self.dernier_mot_de_passe = ''
        for lettre in range(self.nombre_de_carateres):
            self.dernier_mot_de_passe = self.dernier_mot_de_passe + chr(randint(self.ascii_debut, self.ascii_fin))
        self.nombre_de_mots += 1
        return self.dernier_mot_de_passe

    def generate(self, encryption, nombre_de_carateres=int()):
        '''
        could be used to make library of passwords with hash to avoid wasting time by rehashing at every crack
        example:
        >>> pycracker.brute_force().generate("md5", 5)#5 is the lenght of desired password "md5" is the encryption you want
        ['D0!Zc', '807bacbbe4c2fea3723e9f1858fd484c']#return a list with generated pass and hashed generated pass
        '''
        if nombre_de_carateres:
            self.nombre_de_carateres = nombre_de_carateres
        return [self.new(), self.encode(encryption)]


    def encode(self, encryption):
        '''md5, sha1, sha224, sha256, sha384, sha512'''
        self.dernier_mot_de_passe_hashe = getattr(hashlib, encryption)(self.dernier_mot_de_passe).hexdigest()
        return self.dernier_mot_de_passe_hashe



class brute_writer:
    def __init__(self, encryption, nombre_de_carateres_depart=int(1)):
        '''
        A tiny class to generate random passwords 
        and hash it to write it out in files using pickle
        '''
        self.brute = brute_force()
        self.encryption = encryption.lower()
        self.brute.nombre_de_caracteres = nombre_de_carateres_depart
        self.tout_mots = []
        self.compteur = 0

    def __len__(self):
        return self.brute.nombre_de_mots

    def __str__(self):
        return self.brute.nombre_de_mots

    def __del__(self):
        '''Save before any exit'''
        self.on_save()

    def set_char(self, nombre_de_caracteres = 0):
        if not nombre_de_caracteres:
            self.brute.nombre_de_caracteres = nombre_de_caracteres

    def on_save(self):
        '''Save the pass'''
        try:
            mkdir('library')
        except OSError:
            print("\n[*] dir already created")
        file = open("library/dict%sc%i.crack" % (self.encryption, self.brute.nombre_de_caracteres), "a")
        file.write("\n".join(self.tout_mots))
        file.flush()
        fsync(file.fileno())
        file.close()
        self.tout_mots = []

    def make(self, encryption):
        ''''''
        self.compteur += 1
        self.tout_mots.append("\t".join(self.brute.generate(encryption)))



def make_dict(encryption, nombre_de_carateres_depart=1, display=True):
    '''
    generate random passwords and hash it 
    to write it out in files using module
    '''
    m = brute_writer(encryption, nombre_de_carateres_depart)
    if encryption not in ['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512']:
        print("Encryption not found")
        _exit(0)
    while (True):
        try:
            if (m.brute.puissances[m.brute.nombre_de_carateres-1] == m.brute.nombre_de_mots):
                    m.brute.nombre_de_carateres += 1
            if (m.compteur >= 500000):
                #do a backup every x times
                m.on_save()
                m.compteur = 0
                m.tout_mots = []
            m.make(encryption)
            if display:
                stdout.write("\rGenerating: %i" % len(m))
                stdout.flush()
        except KeyboardInterrupt:
            print("\nKeyboard interrupt")
            m.on_save()
            sleep(5)

def crack(encryption, hash_password, display=True):
    '''
    return the password from a hash if found
    >>> import pycracker
    >>> print pycracker.crack("md5", "49f68a5c8493ec2c0bf489821c21fc3b")
    Tested: 3500 passwords searching now with 2 chars
    hi
    '''
    brute = brute_force(hash_password)
    if encryption not in ['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512']:
        print("Encryption not found")
        _exit(0)
    try:
        while (True):
            if (brute.puissances[brute.nombre_de_carateres-1] == brute.nombre_de_mots):
                    brute.nombre_de_carateres += 1
            if (brute.one_search(encryption)):
                print
                return brute.dernier_mot_de_passe
            if display:
                stdout.write("\rTested: %d passwords searching now with %d chars" % (len(brute), brute.nombre_de_carateres))
                stdout.flush()
    except KeyboardInterrupt:
        print("\nKeyboard Interrupt")
        exit()

def crack_with_dict(dict_name, to_crack):
     try:
          file = open(dict_name, "r")
     except IOError:
          print("File not found: %s" % dict_name)
          exit()
     for ligne in file:
          if ligne[ligne.find("\t")+1:].replace("\n", "") == to_crack:
                return ligne[:ligne.find("\t")]
     return ''

def crack_with_file(file_name, encryption, hash_pass):
    brute = brute_force()
    encryption = encryption.lower()
    if encryption not in ['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512']:
        print("Encryption not found")
        _exit(0)
    try:
        _file = open(file_name, "r")
    except IOError:
        return ("File: %s not found" % file_name)
    _file.seek(0)
    print("Cracking...")
    for ligne in _file:
        brute.dernier_mot_de_passe = ligne.replace("\n", "")
        if brute.encode(encryption) == hash_pass:
            return ligne.replace("\n", "")
    print "Not found"

def quitter():
    print("Exitted before found any correspondance")
    _exit(0)

def main():
    '''
    usage:
    [mou@mou pycracker]$ python pycracker.py sha1 1 c22b5f9178342609428d6f51b2c5af4c0bde6a42
    Tested: 1032 passwords searching now with 2 chars
    Found: 
    hi
    [mou@mou pycracker]$
    '''
    register(quitter)
    __help__ = ('''
craken.py: basic help
Usage: python {0} [-c Crack a hash]
                  [-g generate a dict of passwords, encryption as 2nd arguement]
                  [-h display this help]
                  [-f crack a hash using plain text file
                       use -d if you used -g on the file]
                  [-d crack a hash using a dictionary file (use -g to make one)
                    no encryptions arguements needed]
Example:
    python {0} -c md5 "c268120ce3918b1264fe2c05143b5c4b"
                      or
    python {0} -f passwords.txt md5 "c268120ce3918b1264fe2c05143b5c4b"
                      or
    python {0} -d dictmd5c1.crack '61bad16b91c29a757f6b36c21a065197'
    '''.format(argv[0]))
    try:
        if (argv[1].lower() == '-c'):
            try:
                print("\nFound: %s" % crack(argv[2].lower(), argv[3]))
            except IndexError:
                print("More arguements needed\n%s" % __help__)
        elif (argv[1].lower() == '-g'):
            try:
                make_dict(argv[2].lower())
            except IndexError:
                print("More arguements needed\n%s" % __help__)
        elif (argv[1].lower() == '-f'):
            try:
                print("Found: %s" % crack_with_file(argv[2], argv[3].lower(), argv[4]))
            except IndexError:
                print(__help__)
        elif argv[1].lower() == '-d':
             try:
                  print("Found: %s" % crack_with_dict(argv[2], argv[3]))
             except IndexError:
                  print(__help__)
        elif (argv[1].lower() == '-h'):
            print(__help__)
        else:
            print("try: python %s -h" % argv[0])
    except IndexError:
        choix = input("1. Generate a dictionary\n2. Crack a password\n3. Crack a password using a file\n4. Crack a hash using a dictionary file\n: ")
        if (choix == 1):
            make_dict(raw_input("Encryption\nmd5, sha1, sha224, sha256, sha384, sha512\n: "))
        elif (choix == 2):
            print("Found: %s" % crack(raw_input("Encryption\nmd5, sha1, sha224, sha256, sha384, sha512\n: "), raw_input("Data to crack: ")))
        elif (choix == 3):
            print("Found: %s" % crack_with_file(raw_input("File name: "), raw_input("Encryption to crack: ").lower(), raw_input("Hash to crack: ")))
        else:
            print("Found: %s" % crack_with_dict(raw_input("File name: "), raw_input("Hash to crack: ")))
if __name__ == "__main__":
    print("""
                                              ,MD5
                                            ,o
== THE CRAKEN ==                           :o
                   _....._                  `:o
                 .'       ``-.                \o
                /  _      _   \                \o
               :  /*\    /*\   )                ;o
               |  \_/    \_/   /        lulz     ;o
               (       U      /                 ;o
                \  (\_____/) /                  /o
                 \   \_m_/  (                  /o
                  \         (                ,o:
                  )          \,           .o;o'           ,o'o'o.
                ./          /\o;o,,,,,;o;o;''         _,-o,-'''-o:o.
 .sha384      ./o./)        \    'o'o'o''         _,-'o,o'         oSHA1
 o           ./o./ /       .o \.              __,-o o,o'
 \o.       ,/o /  /o/)     | o o'-..____,,-o'o o_o-'
 `o:o...-o,o-' ,o,/ |     \   'o.o_o_o_o,o--''
 .,  ``o-o'  ,.oo/   'o /\.o`.
 `o`o-....o'o,-'   /o /   \o \.                       ,o..         o
sha512`o-o.o--    /o /      \o.o--..          ,,,o-o'o.--o:o:o,,..:oSHA256
                 (oo(          `--o.o`o---o'o'o,o,-'''        o'o'o
                  \ o\              ``-o-o''''
   ,-o;osha224     \o \
  /o/               )o )
 (o(               /o / 
  \o\.       ...-o'o /
    \o`o`-o'o o,o,--'
      ```o--''' """)
    main()
    _exit(0)

[信用]

* 在超级计算机上

于 2013-08-06T13:29:53.863 回答
0

我解决了这个问题,并认为我会在这里分享。希望我不会引起社区的太多愤怒。md5hash所以,问题是,变量和变量之间总是存在不匹配的localtemphash。在重新阅读代码数百次后,检查了 PHP 代码的逻辑流程并回显了每一行的输出,我想出了答案。编码会添加换行符,这些也会被 md5 算法散列(我不知道)。感谢所有为我指明方向的人,尤其是 MGetz。所以对于那些想要代码的人来说,这里是:

                        data_encoded = serialize(results)
                        data_encoded = data_encoded.replace("\n","")
                        data_encoded = data_encoded.replace(" ","")
                        print "\n\n Serialized\n"+data_encoded+"\n\n"
                        data_encoded = data_encoded.encode('base64')
                        data_encoded = data_encoded.replace("\n","")
                        data_encoded = data_encoded.replace(" ","")
                        print "\n\n ENCODED\n"+data_encoded+"\n\n"
                        thishex = md5(str(checkdate)+licensing_secret_key)
                        thishash = thishex.hexdigest()
                        data_encoded = thishash+data_encoded
                        data_encoded = data_encoded.replace("\n","")
                        data_encoded = data_encoded.replace(" ","")
                        print "\n\n MD5ed\n"+data_encoded+"\n\n"
                        data_encoded = data_encoded[::-1]
                        data_encoded = data_encoded.replace("\n","")
                        data_encoded = data_encoded.replace(" ","")
                        print "\n\n Rverserd\n"+data_encoded+"\n\n"
                        thathex = md5(data_encoded+licensing_secret_key)
                        thathash = thathex.hexdigest()
                        print "\n\n\n THAT HASH\n"+thathash+"\n\n"

                        data_encoded = data_encoded+ thathash
                        data_encoded = data_encoded.replace("\n","")
                        data_encoded = data_encoded.replace(" ","")
                        print "\n\n MD5ed\n"+data_encoded+"\n\n"
                        data_encoded = textwrap.fill(data_encoded,70)

我在问题中使用了一些错误的术语,例如解密,这不是我想要做的——现在我知道了区别。解决方案是删除换行符和空格,并且检查部分有效。

感谢大家..

于 2013-08-07T07:27:56.930 回答