Generische Salts

Du hast eine Idee für ein Projekt?
Antworten
ihucos
User
Beiträge: 8
Registriert: Dienstag 11. November 2014, 11:37

Hallo!

die Idee schwirrte mir schon eine weile im Kopf, ob das sinnvoll ist. Ich habe es mal einfach implementiert.
Und zwar hashing verbunden mit einem etwas anderes Proof of Work. Vor dem Hashing wird aus einer großen Datei einen für das zu hashende Element zuordenbares Teil als Salt benutzt. Wenn man also hashen will, braucht man entweder diese 34 Terabyte Lokal, was ärgerlich sein kann oder man muss für jedes hashen einen HTTP request machen, was langsamer ist.
Warum habe ich das jetzt mit den Chunks gemacht? egal, die Idee Zählt.

Macht doch Sinn, oder?
8) 8) 8)


Code: Alles auswählen

import hashlib
import struct

import requests

JUNK = 'http://darksky.slac.stanford.edu/simulations/ds14_a/ds14_a_1.0000'
JUNK_HTTP_CONTENT_LENGTH = 34359739943392  # that is 34 terabytes
CHUNK_SIZE = 64
HASH = 'ripemd160'

chunks_count = int(JUNK_HTTP_CONTENT_LENGTH/CHUNK_SIZE)


def get_junk_chunk(index):
    if index > chunks_count:
        raise ValueError('should not exceed {}'.format(chunks_count))
    start = index * CHUNK_SIZE
    end = start + CHUNK_SIZE - 1
    resp = requests.get(
        JUNK,
        headers={'range': 'bytes={}-{}'.format(start, end)})
    resp.raise_for_status()
    return resp.content


def get_salt(hashable):
    h = hashlib.new(HASH)
    h.update(hashable)
    bytes = h.digest()[:8]
    hash_int = struct.unpack('Q', bytes)[0]
    max_hash_int = 2**64-1
    hash_percent = hash_int/float(max_hash_int)
    index = round(hash_percent * chunks_count)
    return get_junk_chunk(index)


def hash(hashable):
    h = hashlib.new(HASH)
    h.update(hashable + get_salt(hashable))
    return h.hexdigest()


if __name__ == '__main__':
    print(hash('hello world'.encode()))  # fbc9e2bbaf17488e28862475694d6da3c46fa073
    print(hash('hash this'.encode()))  # 869480ba313ec481b5487860bf4e6ff7ef0eae1c
    print(hash('foo bar baz'.encode()))  # d4a728c9681d878c85a0cdfb710134e7c60bef2d
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@ihucos:
Security by obscurity? Das war noch nie eine gute Idee. Mal abgesehen davon, dass die Requestsache extrem fehleranfällig ist (Datei weg oder geändert), hat Dein Salt eine große Schwäche - er ist immer gleich fürs gleiche Ausgangswörter und ist damit strenggenommen kein Salt mehr sondern einfach die Erweiterung des zu Hashenden um x Bytes nach festen Regeln. Hier musst Du Dich erstmal fragen, was Du mit dem Salt erreichen willst - für simple Rehash-Vergleiche geht es einfacher ohne Salt (dafür sind kryptografische Hashalgorithmen ohne Salt gut genug) und fürs Speichern von sicheren Hashes (z.B. von Passwörtern) taugt Dein Verfahren nicht, da der Salt nicht wechselt.
ihucos hat geschrieben:...Macht doch Sinn, oder?...
Ehm nein.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Generell: Wenn du etwas verkaufen willst, dann solltest du auch erklaeren, warum du denn besser bist als die Konkurrenz.

Konkret heisst das im Security-Umfeld: Was ist dein Angriffsszenario, im Normalfall Rainbowtable Angriffe wie sie jerch angesprechen hat, und was macht dein Ansatz besser als andere.
Aber ich glaube das war das Grundproblem: Du benutzt Salts, weil man das eben so macht, aber kennst das genaue Angriffsszenario nicht.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

ihucos hat geschrieben:Vor dem Hashing wird aus einer großen Datei einen für das zu hashende Element zuordenbares Teil als Salt benutzt.
Die Anzahl an Dinge auf die ein Anwender Einfluß hat sind bei kryptographischen Systemen grundsätzlich auf das absolut notwendigste zu beschränken um Fehlerquellen zu minimieren. Man könnte meinen dies wäre offensichtlich, trotzdem tust du das Gegenteil davon.
Wenn man also hashen will, braucht man entweder diese 34 Terabyte Lokal, was ärgerlich sein kann oder man muss für jedes hashen einen HTTP request machen, was langsamer ist.
Weder ist es ärgerlich die Daten lokal vorzuhalten noch wäre es langsam den HTTP Request zu machen. Sowas als Proof-of-Work zu bezeichnen ist aber definitiv beleidigend gegenüber denjenigen die sich mit sowas ernsthaft beschäftigen.

Macht doch Sinn, oder?
Nein, macht es nicht. Kryptographie ist ein unglaublich komplexes Thema, damit beschäftigt man sich nicht mal ebenso. Nimm ein paar Module zum Thema an einer Uni oder auch nur ein MOOC Ding bevor du deine Zeit weiter verschwendest.
ihucos
User
Beiträge: 8
Registriert: Dienstag 11. November 2014, 11:37

Aber ich glaube das war das Grundproblem: Du benutzt Salts, weil man das eben so macht, aber kennst das genaue Angriffsszenario nicht.
Natürlich hat das ganze Vor- und Nachteile, mein Gedanke ist, das man das hier neben einen "normalen" Salz benutzt um besser vor folgenden Szenario gewappnet zu sein:
Benutzername und Passwort-Hashes sind kompromittiert und können gebrute-forced werden. Alles was ich will, ist das hashen, dass man für jeden versuch brauch teurer zu machen. Also in diesen fall ganz konkret: Eine brute-forcen mit reinen ASICs oder GPUS ist nach meinen verständnis erschwert, weil die 32 Terabyte schwieriger "In-Memory" gespeichert werden können.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Für das Problem gibt es mit scrypt und argon2 schon gute und funktionierende Lösungen.

Außerdem muss man die 32TB nicht im Arbeitsspeicher halten. Man kann problemlos den Index auf der GPU oder einem ASIC berechnen, den Salt besorgen und dann den Hash auf der GPU oder einem ASIC berechnen.
Antworten