mixen van de salt in wachtwoord aan de hand van wachtwoord

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • pizzafried
  • Registratie: November 2006
  • Niet online
Vandaag heb ik eens nagedacht over het feit dat men bij hashen van het wachtwoord in combinatie met een, al dan niet random, salt deze voor of achter het gehashte wachtwoord plaatsen in de database. Op die manier zou in theorie de salt gevonden kunnen worden en zodoende toch het wachtwoord gevonden kunnen worden. Dit in het achterhoofd hebbende kwam ik tot het volgende idee: We gaan het wachtwoord hashen op de conventionele manier met een random salt. Vervolgens ga ik aan de hand van de numerieke ascii karakters en de som van eventuele numerieke karakters van het wachtwoord aan de slag om steeds een stukje van de salt in te voegen in het gehashte wachtwoord. In theorie zou je dan alleen de salt terug kunnen vinden aan de hand van het wachtwoord, heb je geen wachtwoord, dan is het gehashte wachtwoord dus in theorie eigenlijk onbruikbaar.

Ik heb ook al een prototype gebouwd. hash_password zal het wachtwoord hashen en mixen met de salt, compare_password gaat met het gegeven wachtwoord het proces omkeren en de salt er uitfilteren. Ik heb het getest, en de code werkt.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?php
function hash_password($password, $hash = null) {
    $salt = (is_null($hash)) ? sha1(md5(time().rand(0, 9999) + strlen($password))) : $hash;
    for ($i = 0; $i < 10000; $i++) $saltedPassword = sha1($password . $salt);
    $sumord = strlen($password);
    $sumnr = 1;
    while (true) {
        if (strlen($salt) <= 0) break;
        for ($i = 0; $i < strlen($password); $i++) {
            if (strlen($salt) <= 0) break;
            $ord = ord($password[$i]);
            $sumord += $ord;
            if (ctype_digit($password[$i])) $sumnr += $password[$i];
            $key = $sumnr * $sumord;
            $position = $key % 40;
            $group = ($sumord % 2) ? 3 : 2;
            if (strlen($salt) < $group) $group = strlen($salt);
            if ($key % 2) {
                $saltedPassword = substr($saltedPassword, 0, $position) . substr($salt, 0, $group) . substr($saltedPassword, $position);
                $salt = substr($salt, $group, strlen($salt));
            } else {
                $saltedPassword1 = substr($saltedPassword, 0, strlen($saltedPassword) - $position);
                $saltedPassword = $saltedPassword1 . substr($salt, strlen($salt) - $group, strlen($salt)) . substr($saltedPassword, strlen($saltedPassword1));
                $salt = substr($salt, 0, strlen($salt) - $group);
            }
        }
    }
    return $saltedPassword;
}

function compare_password($password, $saltedPassword) {
    $sumord = strlen($password);
    $sumnr = 1;
    $decoders = array();
    $salt = sha1("dummyhash");
    while (true) {
        if (strlen($salt) <= 0) break;
        for ($i = 0; $i < strlen($password); $i++) {
            if (strlen($salt) <= 0) break;
            $ord = ord($password[$i]);
            $sumord += $ord;
            if (ctype_digit($password[$i])) $sumnr += $password[$i];
            $key = $sumnr * $sumord;
            $position = $key % 40;
            $group = ($sumord % 2) ? 3 : 2;
            if (strlen($salt) < $group) $group = strlen($salt);
            $decoders[] = array("ord" => $ord, "sumord" => $sumord, "sumnr" => $sumnr, "group" => $group, "key" => $key);           
            $salt = substr($salt, $group, strlen($salt));   
        }
    }
    $decoders = array_reverse($decoders);
    $salt = "";
    $unsaltedPassword = $saltedPassword;
    foreach ($decoders as $decoder) {
        if (strlen($salt) >= 40) break;
        $position = $decoder['key'] % 40;
        if ($decoder['key'] % 2) {
            $salt = substr($unsaltedPassword, $position, $decoder['group']) . $salt;
            $unsaltedPassword = substr($unsaltedPassword, 0, $position) . substr($unsaltedPassword, $position + $decoder['group']);
        } else {
            $salt .= substr($unsaltedPassword, strlen($unsaltedPassword) - ($position + $decoder['group']), $decoder['group']);
            $unsaltedPassword = substr($unsaltedPassword, 0, strlen($unsaltedPassword) - ($position + $decoder['group'])) . substr($unsaltedPassword, (strlen($unsaltedPassword) - $position));
        }
    }
    return $saltedPassword == hash_password($password, $salt);
}
?>


Mijn vraag aan jullie is: Heb ik nu iets gemaakt dat niet gaat werken of heb ik dubbel werk geleverd?

Acties:
  • 0 Henk 'm!

  • Ventieldopje
  • Registratie: December 2005
  • Laatst online: 10:59

Ventieldopje

I'm not your pal, mate!

Op die manier zou in theorie de salt gevonden kunnen worden en zodoende toch het wachtwoord gevonden kunnen worden.
Ik denk het niet ;) Het is wel een leuk concept wat je hebt bedacht maar of het veel toe zal voegen weet ik niet, het geeft wel wat extra belasting op je server.

www.maartendeboer.net
1D X | 5Ds | Zeiss Milvus 25, 50, 85 f/1.4 | Zeiss Otus 55 f/1.4 | Canon 200 f/1.8 | Canon 200 f/2 | Canon 300 f/2.8


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Heel verhaal om de salt te verbergen, terwijl de salt helemaal niet geheim gehouden hoeft te worden...
The salt does not need to be secret. Just by randomizing the hashes, lookup tables, reverse lookup tables, and rainbow tables become ineffective. An attacker won't know in advance what the salt will be, so they can't pre-compute a lookup table or rainbow table. If each user's password is hashed with a different salt, the reverse lookup table attack won't work either.
Geen hash-functies chainen, geen "al dan niet random" salt, maar een cryptografisch sterke random salt per gebruiker meenemen bij het hashen met een enkele goede hash-functie dus. Die salt kun je gewoon opslaan in de database. In PHP hash en check je dan bijv. op deze manier: http://crackstation.net/hashing-security.htm#phpsourcecode

[ Voor 24% gewijzigd door Herko_ter_Horst op 17-09-2012 15:35 ]

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • pizzafried
  • Registratie: November 2006
  • Niet online
die theorieen ken ik en heb ik gelezen, maar het gaat bijvoorbeeld om attacks om iemand, één persoon, zwart te maken. Heeft die dan een zwak wachtwoord en de salt is bekend (door dat de salt zichtbaar aan de voorkant of aan de achterkant is geplakt) heb je zo alsnog even veel kans met vooraf berekende rainbow tabellen op basis van de salt het wachtwoord te vinden, iets wat je met een onbekende salt niet hebt. Persoonlijk denk ik dat daar het voordeel ligt in dit systeem. niet zo zeer in de wachtwoord dieven die alle wachtwoorden willen stelen en gebruiken om andere accounts lastig te vallen, die zo overigens ook buiten de boot vallen...overigens, zoals je kunt zien wordt hier overigens ook voor iedere user een random salt gegenereerd en het wachtwoord en salt 10.000 keer gehashed.

Acties:
  • 0 Henk 'm!

Verwijderd

Henze schreef op maandag 17 september 2012 @ 16:59:
Heeft die dan een zwak wachtwoord en de salt is bekend (door dat de salt zichtbaar aan de voorkant of aan de achterkant is geplakt) heb je zo alsnog even veel kans met vooraf berekende rainbow tabellen op basis van de salt het wachtwoord te vinden,
Voor elke bit dat de salt lang is, moet de rainbow table 2x zo groot worden om hetzelfde effect te hebben. Het gaat dan ook niet om het onmogelijk maken om rainbow tables te gebruiken, maar om het onpraktisch te maken.

Voor jouw hash functie is ook een rainbow table te maken.

Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Er zijn ook meerdere topics geweest met info hoe je het beste om kan gaan met je wachtwoord, hashes, salts (en wel of geen pepper) :)

http://gathering.tweakers...rchtimeout%5D=30#hitstart

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Mooi stukje ingewikkelde code, maar helaas maakt het de boel vooral onveiliger. Voor sha1(md5(time().rand(0, 9999) + strlen($password))) is maar een beperkte hoeveelheid mogelijkheden, zeker als je de tijd weet, en daar kun je een tabelletje van maken. Vervolgens kun je mogelijke salts gaan matchen, en krijg je informatie over het wachtwoord!

Voor welk probleem is deze oplossing eigenlijk een oplossing? Wat zou hier beter aan zijn dan gewoon iets als bcrypt gebruiken? ;)

Waarom trouwens dit onzinloopje?
Henze schreef op maandag 17 september 2012 @ 15:16:
PHP:
3
    for ($i = 0; $i < 10000; $i++) $saltedPassword = sha1($password . $salt);

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • pizzafried
  • Registratie: November 2006
  • Niet online
Het is natuurlijk wel een prototype, een idee, ik zou natuurlijk iets andere hash methodes kunnen gebruiken zoals idd bcrypt...over de salt heb je gelijk, ik heb die inmiddels vervangen voor een wat meer random functie. Al kan je ook gewoon zelf een salt opgeven als je deze functie zou gebruiken.

PHP:
1
2
3
<?php
       substr(base64_encode(mt_rand(1,9999999999)),0,10);
?>

all heeft deze ook wat kanttekeningen, je zou deze meerdere keren kunnen genereren en dan een randomlengte nemen en deze resultaten samenvoegen waardoor je een salt krijgt met variabele lengte.

dat onzinloopje wordt trouwens overal op internet aangeraden, ik hoef het 1x te doen, iemand die de wachtwoorden wil kraken/raden veel vaker achter elkaar, waarbij dit het proces zou moeten vertragen en onpraktisch maken. in geval van bcrypt zou dat kunnen vervallen.

Het idee was dat dit rainbowtables vrijwel onmogelijk zou moeten maken, maar ik zie nu in dat dat ook hiermee niet mogelijk is. Wel zou dit, gezien ook gezegt is dat dit extra serverbelasting op zou leveren deze rainbowtables nog verder onpraktisch kunnen maken...

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
mt_rand lijkt me sowieso een beperkt aantal mogelijke waardes produceren bij een bekende tijd, zeker als je het PID weet te achterhalen (waarschijnlijker vanwege uitlekken passworddatabase), zie http://stackoverflow.com/...ow-is-phps-mt-rand-seeded

Het onzinloopje doet in jouw geval vooralsnog niets extras, dan zul je toch de rechterkant variabel moeten hebben, dus zeg $saltedPassword = $password, en dan $saltedPassword aan de rechterkant. Maar het is inderdaad wel ongeveer het concept dat bcrypt gebruikt. Het voordeel van bcrypt ten opzichte van jouw methode is echter dat je bcrypt makkelijk kan versterken zonder de wachtwoorden te weten. Daarnaast is het een proven methode, je ziet al weer hoe makkelijk het is om een foutje te maken waardoor het juist onveiliger wordt als je zelf iets gaat verzinnen.

Wat bijvoorbeeld hier ook zou kunnen gebeuren, is dat te veel wachtwoorden gaan valideren doordat de salt vrijer gekozen kan worden uit de beschikbare data. Daarom lijkt het me handiger om een reeds bestaande, geverifieerde en veel geteste methode te gebruiken ;)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
pedorus schreef op dinsdag 18 september 2012 @ 11:37:
Maar het is inderdaad wel ongeveer het concept dat bcrypt gebruikt.
Niet echt; bij bcrypt, pbkdf2 en consorten verandert de uiteindelijke hash wel elke iteratie. En dat doet 't bij TS niet. Of ik mis iets (of begrijp bcrypt/pbkdf2 verkeerd :P ).

[ Voor 37% gewijzigd door RobIII op 18-09-2012 11:51 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • pizzafried
  • Registratie: November 2006
  • Niet online
@Robill idd zie net dat die implementatie wel heel erg fout gaat. Idee was wel de hash bij iedere iteratie anders te laten overkomen, maar hier herhaal ik de operatie gewoon 10.000 keer 8)7 , en dan begrijp ik het verhaal over het onzinloopje

PHP:
1
2
3
4
<?php
    $saltedPassword = sha1($salt.$password);
    for ($i = 0; $i < 10000; $i++) $saltedPassword = sha1($salt.$saltedPassword); 
?>

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Mja, either way: waarom 't wiel opnieuw (en vierkant) uitvinden? Gebruik gewoon beproefde methodes, dat is eigenlijk les #1 in security. Daar kun je het hele topic mee afdoen (zonder afbreuk te willen doen aan je intenties).

offtopic:
En mijn nick is RobIII, niet Robill; zie ook mijn ondertitel: "^ Romeinse 3 ja!" ;)

[ Voor 42% gewijzigd door RobIII op 18-09-2012 12:11 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij

Pagina: 1