Seite 1 von 1

MD5 - Crypter

Verfasst: Dienstag 27. Februar 2018, 09:47
von Furbynat0r
Hallo Leute,

ich bin gerade dabei mit Verschlüsselungen usw rumzuspielen. Ich weiß, das MD5 ausgelutscht und unsicher ist, allerdings dient dies nur dem Lernzweck :).

Ich möchte gerne das mein Script das Salt nimmt und dieses mit MD5 verschlüsselt. Danach wird das Passwort genommen und dies auch mit MD5 verschlüsselt.

Danach sollen die beiden Hashwerte aneinander gesetzt werden (salt,passwort) und das nochmals mir MD5 verschlüsselt werden.

Mein Script schaut aktuell so aus:

Code: Alles auswählen

import hashlib
name = b"passwort"
salt = b"salt"

passwort = hashlib.md5(name)
salz = hashlib.md5(salt)

ab = (passwort.hexdigest())
ac = (salz.hexdigest())

fertig = ac,ab

salti = hashlib.md5(fertig)
print (salti.hexdigest())
Ich weiß, den Code könnte man noch optimieren :D.

Es geht mir nur darum, wenn ich das ausführe, dann erhalte ich den Fehler:
TypeError: object supporting the buffer API required

Ich werde aktuell überhaupt nicht schlau wo der Fehler ist :(.

Danke für eure Hilfe :)

Re: MD5 - Crypter

Verfasst: Dienstag 27. Februar 2018, 10:39
von Sirius3
@Furbynat0r: `fertig` ist ein Tuple und von Tuple können keine Hashes gebildet werden. Erzeuge einen String, wandle diesen in in Bytes um, und dann hast Du wieder etwas, über das man einen Hash berechnen kann.

Re: MD5 - Crypter

Verfasst: Dienstag 27. Februar 2018, 11:57
von Furbynat0r
Ah ok :)

Habs soweit umgebaut und es funtkioniert sogar :)....

Code: Alles auswählen

import hashlib
name = b"testen"
salt = b"0xWFlX3w"
 
passwort = hashlib.md5(name)
salz = hashlib.md5(salt)
 
ab = (passwort.hexdigest())
ac = (salz.hexdigest())
 
fertig = ac,ab

string = ''.join(fertig)
byt = bytes(string,'UTF-8')

fertighash = hashlib.md5(byt)
fertigencode = fertighash.hexdigest()
print(fertigencode)
Jetzt würde mich zum abschluss einfach interessieren, wie man den Code noch etwas optimiert.

Vielen Dank für deine Hilfe!! :)

Re: MD5 - Crypter

Verfasst: Dienstag 27. Februar 2018, 12:07
von DasIch
Unabhängig davon das MD5 unsicher ist und auch noch nie wirklich dafür geeignet war Passwörter zu hashen, ist es komplette Zeitverschwendung den Salt zu hashen.

Wenn du dies nicht mehr tust, hast du auch gleich den Code optimiert.

Re: MD5 - Crypter

Verfasst: Dienstag 27. Februar 2018, 13:09
von Sirius3
@Furbynat0r: wenn man exakt zwei Elemente hat, und die auch noch extra in ein Tupel packt, dann ist join die falsche Methode. join verwendet man für Listen mit beliebiger Anzahl an Elementen.

`ac`, `ab`, `fertig` und `byt` sind schlechte Namen, weil sie nichts aussagen.

Am besten schreibt man sich eine Funktion, für Dinge, die immer wieder auftreten:

Code: Alles auswählen

import hashlib

def md5hex(bytes):
    return hashlib.md5(bytes).hexdigest().encode('ASCII')

password = b"testen"
salt = b"0xWFlX3w"
 
hash = md5hex(md5hex(password) + md5hex(salt))
print(hash)

Re: MD5 - Crypter

Verfasst: Mittwoch 28. Februar 2018, 10:46
von DeaD_EyE
Gestern habe ich mich in bisschen in sqlite3 eingearbeitet.
Ich habe eine kleine Datenbank für Logins angelegt.
Hier mal einen Ausschnitt aus dem Code, wie ich die Hashes generiere:

Code: Alles auswählen

import hashlib
import os


def gen_salt():
    """
    Generates a salt with 10 bytes
    """
    return os.urandom(10)


def hash_pw(password, salt):
    """
    Hashes each password with a given salt.
    :param password: str
    :param salt: bytes
    :return: hashed password as bytes
    """
    return hashlib.pbkdf2_hmac('sha512', password.encode(), salt, 10)


def check_pw(password, hash, salt):
    """
    Checks the password with given hash and salt.
    :param password: str
    :param hash: bytes
    :param salt: bytes
    :return: bool
    """
    pw_hash = hash_pw(password, salt)
    return pw_hash == hash
Ich speichere einfach für jeden User einen individuellen Hash. Keine Ahnung ob das überhaupt notwendig ist, aber ich mache das so.
Wenn du dann z.B. einen User anlegen willst:

Code: Alles auswählen

from collections import namedtuple


Row = namedtuple('User', 'username password salt')
username = 'Foo'
password = 'Bar'
salt = gen_salt()
hashed_password = hash_pw(password, salt)

user = Row(username, hashed_password, salt)
print(user)

Code: Alles auswählen

User(username='Foo', password=b"TX\x99\xd5UH\xbd\x0e/\xc4\x114\xd3pN\xed\x9f\xf9yp\xdb\x18\xf4\x95_\x13*'C*\x0f\x1d\x93\xf5\x08b8\x06\xa0.\xff\x04\xe8=B.\x18\x16:\x93\xdf\xbb\x94'\x01\x90\x19O\xb0\xf4\xb5\xd2\xeeV", salt=b'U\x00?\xce\x02$\xb2B\xfa\x03')
Nun das eingegebene Passwort überprüfen:

Code: Alles auswählen

wrong_password = 'Foo'
right_password = 'Bar'

if check_pw(wrong_password ,user.password, user.salt):
   print(wrong_password, 'is ok.')
else:
   print(wrong_password, 'is wrong.')


if check_pw('Bar' ,user.password, user.salt):
    print(right_password, 'is ok')
else:
    print(right_password, 'is wrong.')
Falls noch grobe Fehler drin sind, bitte sagen. Ich bin auch noch dabei zu lernen was Sicher ist und was man besser gar nicht tun sollte.

Re: MD5 - Crypter

Verfasst: Mittwoch 28. Februar 2018, 11:44
von DeaD_EyE
Update: Schau mal hier: https://docs.python.org/3.6/library/crypt.html#examples

Da ist es noch einfacher. Zuerst generierst du einen Hash:

Code: Alles auswählen

import crypt
import hmac


my_clear_text_password = 'FooBar'
password_in_database = crypt.crypt(my_clear_text_password)

password_to_check = 'FooBar'

#password check
is_valid = hmac.compare_digest(crypt.crypt(password_to_check, password_in_database), password_in_database)
compare_digest umgeht timing attacks und crypt.crypt kümmert sich um gute Hashwerte.

Re: MD5 - Crypter

Verfasst: Mittwoch 28. Februar 2018, 12:44
von DasIch
crypt ist nur minimal besser als MD5. pbkdf2 ist mit sinnvollen Parametern eine gute Wahl, bei 10 Iterationen kann man aber tatsächlich auch einfach crypt nutzen.

Grundsätzliche Empfehlung: Wenn man nicht bereit ist sich im Detail mit der Problematik auseinanderzusetzen, sollte man da einen sehr großen Abstand halten.

Re: MD5 - Crypter

Verfasst: Mittwoch 28. Februar 2018, 15:26
von DeaD_EyE
Hab mal gegeoogelt.

Zu crypt: https://en.wikipedia.org/wiki/Crypt_(Unix)
Zusammenfassung: Ist gebrochen, ist obsolete

Zu pbkdf2: https://cryptosense.com/parameter-choice-for-pbkdf2/

Empfohlen wird:
  • 64 bit salt (in meinem Beispiel sind es 80 Bit)
  • SHA-512
  • 10.000 Iterationen
Jedenfalls werde ich noch hmac.compare_digest verwenden und bei pbkdf2 bleiben. Es kommt bei mir zwar nicht auf Sicherheit an, aber ich wollte es schon richtig implementieren. Man kann halt auch ganz viel falsch machen und es funktioniert trotzdem.

Re: MD5 - Crypter

Verfasst: Mittwoch 28. Februar 2018, 20:19
von DasIch
Die Recommendation des Blog Posts ist nicht 10.000, sie ist >=10.000
[...]use an iteration count of at least 10000, more if you can do it “while still allowing acceptable server performance”.
Man sollte also ernsthaft überlegen mehr zu nutzen, wenn man in die Vergangenheit reist, den die Empfehlung kommt aus 2016.

1Password welches auch diesen Algorithmus nutzt, verwendet 100.000 Iterationen. Django tut dies ebenfalls und dass auch schon seit einem Jahr.

10.000 ist also ein bis zwei Größenordnungen von richtig entfernt, wer im Trend liegen will ist vielleicht schon bei 1.000.000 Iterationen.

Das sich dieser Parameter so oft ändert, führt auch zu einem zweiten Problem. Man braucht zwingend einen Mechanismus um diese Parameter zu verändern, ggfs. sogar den Algorithmus selbst falls dieser mal unsicher wird.