Mooie Heisenbug als dat het heeft opgelost
Mijn typkunst...
Typo, sorry
Wat mij trouwens ineens opvalt... zelfs comments eindig ik met een ;
En na even checken... zie ik dat bijna overal in mijn code terugkomen.. en ook in mijn gewone tekstverwerk-acties op een aantal plekken... WTF!
Ben allang blij dat het niet een copy-paste van de live site was nu... Ben ik net thuis, blijkt die hele site al een halve dag plat te liggen
Nee, op de site zelf staat de typo er gelukkig niet.
[ Voor 65% gewijzigd door Firesphere op 25-04-2012 18:35 ]
I'm not a complete idiot. Some parts are missing.
.Gertjan.: Ik ben een zelfstandige alcoholist, dus ik bepaal zelf wel wanneer ik aan het bier ga!
Jammer dat case zonder expliciete jump-operator niet mag in C#..oisyn schreef op woensdag 25 april 2012 @ 15:41:
Die oplossing behandel ik toch ook gewoon?
"maar dat wordt wat lastiger als er veel afhankelijke lokale state is"
Moet je dus alsnog goto gebruiken, de kosmologische constante van de programmeertalen.
Flash is not dead yet? Lets kill it with taxes.alienfruit schreef op donderdag 29 maart 2012 @ 08:41:
[...]
Alleen voor webgames. Het geld niet voor AIR based applicaties. 9% Angry Birds op Facebook is natuurlijk wel leuk voor Adobe. Maar goed, ik weet echt niet meer wat ze aan het doen zijn bij Adobe. Stelletje idioten
Claude: "Domain patterns emerge from iteration, not generation." - Tweakers Time Machine Extension | Chrome : FF
De "as"-operator returned een null als de waarde niet gecast kan worden, gaat dus zelfs goed als de sessionvariabele iets anders is dan de bedoelde uitkomst.farmertjes schreef op woensdag 25 april 2012 @ 17:15:
Volgens mij krijg je in C# een exception als je niet eerst checkt op null, dus is zijn code wel goed.
De code erboven klopt ook gewoon, dat is de gewoon de property syntax voor C#.
Vooraf checken op null is dus volledig overbodig.
De hele routine had in 1 simpele property geschreven kunnen worden:
C#:
1
2
3
4
5
| public SearchFilterCompany SearchFilter { get { return HttpContext.Current.Session[SessionKeySearchFilter] as SearchFilterCompany; } set { HttpContext.Current.Session[SessionKeySearchFilter] = value; } } |
De class wordt iedere keer opnieuw geinstantieerd en het is een reference. Dus daar zal het net goed gaan...MatHack schreef op woensdag 25 april 2012 @ 17:22:
_filter wordt toch echt gevuld met het resultaat van de methode GetSearchFilter().
Die viel me inderdaad pas later op en daar heb ik ook al meerdere (op andere plekken) van opgeruimd....MatHack schreef op woensdag 25 april 2012 @ 17:22:
Ik vind de "as SearchFilterCompany" in de SetSearchFilter() toch echt het mooiste staaltje onzin.
[ Voor 27% gewijzigd door HeSitated op 25-04-2012 20:50 ]
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
| public SearchFilterCompany SearchFilter { get { if(HttpContext.Current.Session[SessionKeySearchFilter] == null) { HttpContext.Current.Session[SessionKeySearchFilter] = new SearchFilterCompany(); } return HttpContext.Current.Session[SessionKeySearchFilter] as SearchFilterCompany; } set { HttpContext.Current.Session[SessionKeySearchFilter] = value; } } |
Zo moet hij volgens mij
We are shaping the future
Jullie gaan alleen allemaal voorbij aan het feit dat Session zélf ook null kan zijn (tijdens Application_Start)
Kater? Eerst water, de rest komt later
Dit zie ik ook wel eens voorbij komen:
Het gaat dus om de check of de oude waarde niet toevallig hetzelfde is als de nieuwe waarde, waar is dat nou voor nodig?
Kijk, als je een property hebt die PropertyChanged afvuurt, dan snap ik het.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
| private string _testProperty = string.Empty; public string TestProperty { get { return _testProperty; } set { if (_testProperty != value) { _testProperty = value; } } } |
Het gaat dus om de check of de oude waarde niet toevallig hetzelfde is als de nieuwe waarde, waar is dat nou voor nodig?
Kijk, als je een property hebt die PropertyChanged afvuurt, dan snap ik het.
Ook, helaas, bij de Hema kun je een negatief aantal dagkaarten bestellen.. http://nsdagkaart.hema-actie.nl/ Of meer dan 12, wat je ook maar wilt..
Hmm, ik had er -12 besteld, maar de iDeal-pagina geeft aan dat -198 euro een ongeldig bedrag isEnfer schreef op zondag 29 april 2012 @ 03:05:
Ook, helaas, bij de Hema kun je een negatief aantal dagkaarten bestellen.. http://nsdagkaart.hema-actie.nl/ Of meer dan 12, wat je ook maar wilt..
If money talks then I'm a mime
If time is money then I'm out of time
Haha leuk. Helaas is dit niet echt uit te buiten omdat er gelijk een iDeal aan gekoppeld is. Tenzij je natuurlijk meer dan 12 wilt
.
Hoe zorgen jullie er trouwens voor dat die negatieve optie mogelijk is? Ik heb het net geprobeerd door in Chrome met de dev tool een <option /> aan die dropdown toe te voegen met de console, en die daarna geselecteerd. Kan het ook nog anders?
Hoe zorgen jullie er trouwens voor dat die negatieve optie mogelijk is? Ik heb het net geprobeerd door in Chrome met de dev tool een <option /> aan die dropdown toe te voegen met de console, en die daarna geselecteerd. Kan het ook nog anders?
[quote]Davio schreef op donderdag 26 april 2012 @ 12:18:
Dit zie ik ook wel eens voorbij komen:
[code=c#]
private string _testProperty = string.Empty;
public string TestProperty
{
get { return _testProperty; }
set
{
if (_testProperty != value)
{
_testProperty = value;
}
}
}
[/code]
Het gaat dus om de check of de oude waarde niet toevallig hetzelfde is als de nieuwe waarde, waar is dat nou voor nodig?
Kijk, als je een property hebt die PropertyChanged afvuurt, dan snap ik het.
[/quote]
In het voorbeeld wat je daar geeft zal het niet zoveel uitmaken. Als er in de setter nog een NotifyPropertyChanged aangeroepen word kan het wel handig zijn. Je wilt geen change events triggeren als er niks veranderd is
Voortaan beter lezen
Dit zie ik ook wel eens voorbij komen:
[code=c#]
private string _testProperty = string.Empty;
public string TestProperty
{
get { return _testProperty; }
set
{
if (_testProperty != value)
{
_testProperty = value;
}
}
}
[/code]
Het gaat dus om de check of de oude waarde niet toevallig hetzelfde is als de nieuwe waarde, waar is dat nou voor nodig?
Kijk, als je een property hebt die PropertyChanged afvuurt, dan snap ik het.
[/quote]
In het voorbeeld wat je daar geeft zal het niet zoveel uitmaken. Als er in de setter nog een NotifyPropertyChanged aangeroepen word kan het wel handig zijn. Je wilt geen change events triggeren als er niks veranderd is
Voortaan beter lezen
Xbox
Even the dark has a silver lining | I'm all you can imagine times infinity, times three
Gewoon van een van de bestaande items de value veranderen. Je hoeft niks toe te voegen.Struikrover schreef op zondag 29 april 2012 @ 11:33:
Haha leuk. Helaas is dit niet echt uit te buiten omdat er gelijk een iDeal aan gekoppeld is. Tenzij je natuurlijk meer dan 12 wilt.
Hoe zorgen jullie er trouwens voor dat die negatieve optie mogelijk is? Ik heb het net geprobeerd door in Chrome met de dev tool een <option /> aan die dropdown toe te voegen met de console, en die daarna geselecteerd. Kan het ook nog anders?
Precies en op een indexChanged event in de dropdown-menu wordt de waarde uit het value-veld overgenomen in de berekening.Avalaxy schreef op zondag 29 april 2012 @ 12:40:
Gewoon van een van de bestaande items de value veranderen. Je hoeft niks toe te voegen.
Jammer dat je niet -6 en + 6 kaartjes kunt toevoegen. Dan was het wel weer nuttig geweest.
If money talks then I'm a mime
If time is money then I'm out of time
Ja dat zegt ie toch zelf al in die post?BM schreef op zondag 29 april 2012 @ 11:36:
[...]
In het voorbeeld wat je daar geeft zal het niet zoveel uitmaken. Als er in de setter nog een NotifyPropertyChanged aangeroepen word kan het wel handig zijn. Je wilt geen change events triggeren als er niks veranderd is
Kijk, als je een property hebt die PropertyChanged afvuurt, dan snap ik het.
[ Voor 9% gewijzigd door .oisyn op 29-04-2012 17:13 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Oh shoot, helemaal gemist.oisyn schreef op zondag 29 april 2012 @ 17:12:
[...]
Ja dat zegt ie toch zelf al in die post?
[...]
Xbox
Even the dark has a silver lining | I'm all you can imagine times infinity, times three
Er zit een hidden <select /> op de pagina die als boodschappenmandje fungeert.Matis schreef op zondag 29 april 2012 @ 13:09:
[...]
Precies en op een indexChanged event in de dropdown-menu wordt de waarde uit het value-veld overgenomen in de berekening.
Jammer dat je niet -6 en + 6 kaartjes kunt toevoegen. Dan was het wel weer nuttig geweest.
We are shaping the future
Ohja, nu zie ik het ook, maar als ik zelf met firebug de selects aanpas, worden ze niet meer meegenomen in de post naar de proces-pagina.Alex) schreef op zondag 29 april 2012 @ 19:33:
Er zit een hidden <select /> op de pagina die als boodschappenmandje fungeert.
Edit; Chrome doet het wel goed. Alleen krijg ik als ik (bijvoorbeeld)
HTML:
1
2
3
4
5
| <select id="product_list" class="scProductSelect" multiple="multiple" style="display:none;" name="product_list[]"> <option id="scoption0" rel="ADMIN" "="" value="ADMIN|1">administratiekosten</option> <option id="scoption1" value="v_1269767|1" rel="v_1269767">NS dagkaart</option> <option id="scoption2" value="v_1269767|-1" rel="v_1269767">NS dagkaart</option> </select> |
Doe, dan krijg ik alleen 1 kaartje te zien / te koop.
[ Voor 43% gewijzigd door Matis op 30-04-2012 20:26 ]
If money talks then I'm a mime
If time is money then I'm out of time
Er loopt een stukje script mee dat de items die aangeschaft moeten worden selecteert. Alleen geselecteerde items worden verwerkt, lijkt het.
We are shaping the future
Ja hoor, V&D slaat wachtwoorden plain text op:
[ Voor 3% gewijzigd door bindsa op 30-04-2012 21:34 ]
Nee hoor, het kan zijn dat het mailtje al is opgesteld voordat het wachtwoord versleuteld wordt en wordt opgeslagen. Zelfde principe heb ik ook in diverse tools moeten bouwen, dan wil men een wachtwoord naar een gebruiker sturen (als het account door iemand anders dan de gebruiker wordt aangemaakt), tja dan moet je wel het wachtwoord voor het versleutelen in de mail zettenT.H. Lassche schreef op maandag 30 april 2012 @ 21:34:
Ja hoor, V&D slaat wachtwoorden plain text op:
[...]
Daarnaast zijn er ook genoeg encrypties die 2-way werken. Die je encrypted wachtwoord dus ook weer kunnen decrypten.
Ik begin me meestal pas zorgen te maken als de forgot password functie mijn oude wachtwoord teruggeeft, dan moet men een reversible encryptie gebruiken of de boel niet versleuteld opslaan. Mijn voorkeur ligt bij hashes in plaats van omkeerbare encrypties. Mocht ooit een db gejat worden samen met de sleutels om te decrypten kunnen ze snel je wachtwoord raden. Bij een one-way hash wordt het wat lastiger
Ik verbaas me er niet meer over als ik een site zie waar het lijkt alsof de passwords als plain-tekst worden opgeslagen. Ik dacht dat je aan redelijk wat regels was gebonden als je profielen bijhield (zeker als er bank/cc gegevens bij zitten), maar of de regels zijn te zacht of men heeft geen boodschap aan regels. Dat is de reden waarom ik voor dat soort sites andere wachtwoorden gebruik dan voor "belangrijke" doelen. Leuk als men een webshop account open weet te maken, ze mogen gerust iets bestellen, ze zullen alleen wel hun eigen iDeal transactie moeten doen
The #1 programmer excuse for legitimately slacking off: "My code's compiling"
Firesphere: Sommige mensen verdienen gewoon een High Five. In the Face. With a chair.
"Je wachtwoord is gewijzigd! Er is een bevestigingsmail verzonden met daarin je nieuwe wachtwoord".Gertjan. schreef op maandag 30 april 2012 @ 21:52:
[...]
maar daar zijn dan weer trucjes als "user must change password on first logon" voor uitgevonden
Dat is maar marginaal beter dan onbeveiligd opslaan, natuurlijk. Iemand die toegang heeft tot je database heeft ook toegang tot je encryptiemethode (vooral als je gewoon een "standaard" encryptie gebruikt)..Gertjan. schreef op maandag 30 april 2012 @ 21:52:
Daarnaast zijn er ook genoeg encrypties die 2-way werken. Die je encrypted wachtwoord dus ook weer kunnen decrypten.
Wachtwoorden moeten gewoon hashed opgeslagen worden, mét salt, en liefst met een trage hashfunctie/meerdere ronden (zie SHA-crypt bijvoorbeeld). Ik mag hopen dat het daar in 2012 over eens zijn?
Zelfs PHP heeft built-in ondersteuning voor salting én voor SHA-crypt (cypt() methode $5$ en $6$) dus webdevelopers hebben echt geen excuus meer. (Moeten ze alleen nog zinnige salts genereren en de crypt() functie juist aanroepen...)
Ben het verder wel met je eens hoor, maar bovenstaande hoeft natuurlijk niet waar te zijn. Kan best zijn dat er ergens op je server een certificaat staat waarmee ge-encrypt wordt. Daar hoef je vanuit de db geen toegang tot te hebben.Soultaker schreef op dinsdag 01 mei 2012 @ 09:12:
[...]
Iemand die toegang heeft tot je database heeft ook toegang tot je encryptiemethode (vooral als je gewoon een "standaard" encryptie gebruikt).
Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info
Accord, dat zou kunnen. Maar als je genoeg skills en know-how hebt om zo'n oplossing veilig te implementeren, dan had je ook gewoon salted hashes kunnen gebruiken; waar ben je dan mee bezig? Ik denk dat in de praktijk webdevelopers die van toeten noch blazen weten een veel groter gevaar zijn.
Gebruikers die verwachten dat je ze hun plain-text wachtwoord kan terugsturen zijn idioten die niet weten wat goed voor ze is. (Dat lijkt me de enige reden om wachtwoorden in plain-text op te slaan, want zelfs voor dingen als hash-based authenticatie hoef je geen plaintext wachtwoorden op te slaan.)
Gebruikers die verwachten dat je ze hun plain-text wachtwoord kan terugsturen zijn idioten die niet weten wat goed voor ze is. (Dat lijkt me de enige reden om wachtwoorden in plain-text op te slaan, want zelfs voor dingen als hash-based authenticatie hoef je geen plaintext wachtwoorden op te slaan.)
Dat is nogal sterke taal, vind je niet? Gebruikers denken niet in het bijzonder over zulk soort dingen na, die willen gewoon inloggen om hun ding te doen. Ik kan m'n oma het niet kwalijk nemen dat ze het wel verwacht.Soultaker schreef op dinsdag 01 mei 2012 @ 09:37:
Gebruikers die verwachten dat je ze hun plain-text wachtwoord kan terugsturen zijn idioten die niet weten wat goed voor ze is.
Inderdaad: "Als ik mijn pincode vergeten ben, krijg ik toch ook mijn oude pincode weer :)"TJHeuvel schreef op dinsdag 01 mei 2012 @ 10:15:
[...]
Dat is nogal sterke taal, vind je niet? Gebruikers denken niet in het bijzonder over zulk soort dingen na, die willen gewoon inloggen om hun ding te doen. Ik kan m'n oma het niet kwalijk nemen dat ze het wel verwacht.
Reden temeer dat jouw oma niet de beveiliging van zo'n website moet dicteren. Niet alleen in haar eigen belang trouwens; tegemoetkomen aan haar wensen betekent dat ook jouw en mijn privacy in het geding komt.TJHeuvel schreef op dinsdag 01 mei 2012 @ 10:15:
Gebruikers denken niet in het bijzonder over zulk soort dingen na, die willen gewoon inloggen om hun ding te doen. Ik kan m'n oma het niet kwalijk nemen dat ze het wel verwacht.
Ik had exact hetzelfde bij wehkamp. Toen ik me laatst registreerde kreeg ik een bevestigingsmail met mijn wachtwoord erin. Overbodig en niet handig vind ik zelf. Als ik het wachtwoord net aangemaakt heb weet ik heus nog wel wat het is. Mocht ik het later vergeten dan verwacht ik een reset wachtwoord functie en ga ik niet in mijn mailtjes lopen spitten.
Eentje van mezelf hoor, het is vrijdagmiddag zeker.
Prima, toch? Dan gaan we 'm initializeren:
En maar niet snappen waar de rode lijn onder Bar.Baz = -1 vandaan komt. Eh, misschien zit je nog vóór de constructor van Foo, waardoor Bar gegarandeerd nog niet geïnitialiseerd is, waardoor je niet direct properties kunt aanspreken?
Natuurlijk.
C#:
1
2
3
4
5
6
7
8
9
10
| class Foo { public Bar Bar { get; set; } public String FooString { get; set; } } class Bar { public int Baz { get; set; } } |
Prima, toch? Dan gaan we 'm initializeren:
C#:
1
2
3
4
5
| var foo = new Foo { FooString = "Qux", Bar.Baz = -1 }; |
En maar niet snappen waar de rode lijn onder Bar.Baz = -1 vandaan komt. Eh, misschien zit je nog vóór de constructor van Foo, waardoor Bar gegarandeerd nog niet geïnitialiseerd is, waardoor je niet direct properties kunt aanspreken?
C#:
1
| Bar = new Bar { Baz = -1 } |
Natuurlijk.
https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...
Ik gebruik LastPass voor het beheren van mijn wachtwoorden. Dat heeft er mede voor gezorgd dat ik op heel veel onbenullige sites mijn wachtwoord niet eens weet. Maar laat invullen door LastPass.Chrizzly schreef op dinsdag 01 mei 2012 @ 11:19:
Ik had exact hetzelfde bij wehkamp. Toen ik me laatst registreerde kreeg ik een bevestigingsmail met mijn wachtwoord erin. Overbodig en niet handig vind ik zelf. Als ik het wachtwoord net aangemaakt heb weet ik heus nog wel wat het is. Mocht ik het later vergeten dan verwacht ik een reset wachtwoord functie en ga ik niet in mijn mailtjes lopen spitten.
De wachtwoorden van internetbankieren en mijn email heb ik niet opgeslagen in LastPass.
If money talks then I'm a mime
If time is money then I'm out of time
Klein vraagje:
Ik ben bezig met een applicatie op een Android-tablet die via wifi verbinding maakt met een server.
Helaas krijg ik regelmatig connection-time-outs of socket-time-outs. Dit lijkt heel onregelmatig te zijn, want na nog eens proberen krijg ik geen time-out en kan ik communiceren met de server.
Ik heb dit nu opgelost dat als hij een connection-time-out of socket-time-out krijgt, maximaal 5 keer opnieuw probeert om verbinding te leggen. Dit is natuurlijk hartstikke fout om dit probleem te negeren maar voorlopig heb ik geen betere oplossing gevonden.
Zijn jullie ook wel eens tegen dit soort verbindingsproblemen aangelopen, en hoe hebben jullie dat opgelost?
Ik ben bezig met een applicatie op een Android-tablet die via wifi verbinding maakt met een server.
Helaas krijg ik regelmatig connection-time-outs of socket-time-outs. Dit lijkt heel onregelmatig te zijn, want na nog eens proberen krijg ik geen time-out en kan ik communiceren met de server.
Ik heb dit nu opgelost dat als hij een connection-time-out of socket-time-out krijgt, maximaal 5 keer opnieuw probeert om verbinding te leggen. Dit is natuurlijk hartstikke fout om dit probleem te negeren maar voorlopig heb ik geen betere oplossing gevonden.
Zijn jullie ook wel eens tegen dit soort verbindingsproblemen aangelopen, en hoe hebben jullie dat opgelost?
Speel ook Balls Connect en Repeat
Na 16:30 mag je ook niet meer programmeren op vrijdag. Je kent de regels toch.CodeCaster schreef op vrijdag 04 mei 2012 @ 16:52:
Eentje van mezelf hoor, het is vrijdagmiddag zeker.
C#:
1 2 3 4 5 6 7 8 9 10 class Foo { public Bar Bar { get; set; } public String FooString { get; set; } } class Bar { public int Baz { get; set; } }
Prima, toch? Dan gaan we 'm initializeren:
C#:
1 2 3 4 5 var foo = new Foo { FooString = "Qux", Bar.Baz = -1 };
En maar niet snappen waar de rode lijn onder Bar.Baz = -1 vandaan komt. Eh, misschien zit je nog vóór de constructor van Foo, waardoor Bar gegarandeerd nog niet geïnitialiseerd is, waardoor je niet direct properties kunt aanspreken?
C#:
1 Bar = new Bar { Baz = -1 }
Natuurlijk.
Zeker waar, maar ben het wel met TJHeuvel eens dat dat geen reden is om alle leken op dit vlak idioten te noemen.Soultaker schreef op dinsdag 01 mei 2012 @ 10:53:
[...]
Reden temeer dat jouw oma niet de beveiliging van zo'n website moet dicteren. Niet alleen in haar eigen belang trouwens; tegemoetkomen aan haar wensen betekent dat ook jouw en mijn privacy in het geding komt.
[ Voor 21% gewijzigd door Michali op 04-05-2012 21:44 ]
Kan me nog één andere reden indenken en dat is 'nieuwe wachtwoord moet minimaal X karakters verschillen met laatste Y wachtwoorden'; zo'n compleet nutteloze averechtse policy die veel bedrijven toch nog wel eens afgedwongen willen hebben.Soultaker schreef op dinsdag 01 mei 2012 @ 09:37:
Gebruikers die verwachten dat je ze hun plain-text wachtwoord kan terugsturen zijn idioten die niet weten wat goed voor ze is. (Dat lijkt me de enige reden om wachtwoorden in plain-text op te slaan, want zelfs voor dingen als hash-based authenticatie hoef je geen plaintext wachtwoorden op te slaan.)
Een nieuw wachtwoord instellen bij de RuG is ook altijd een feest: http://www.rug.nl/medewer...etenswaardigheden?lang=nlR4gnax schreef op vrijdag 04 mei 2012 @ 22:41:
[...]
Kan me nog één andere reden indenken en dat is 'nieuwe wachtwoord moet minimaal X karakters verschillen met laatste Y wachtwoorden'; zo'n compleet nutteloze averechtse policy die veel bedrijven toch nog wel eens afgedwongen willen hebben.
Verwijderd
Daar heb je helemaal geen plaintext voor nodigR4gnax schreef op vrijdag 04 mei 2012 @ 22:41:
[...]
Kan me nog één andere reden indenken en dat is 'nieuwe wachtwoord moet minimaal X karakters verschillen met laatste Y wachtwoorden'; zo'n compleet nutteloze averechtse policy die veel bedrijven toch nog wel eens afgedwongen willen hebben.
Urgh. Wat is er zo speciaal aan het & teken dat dát niet gebruikt mag worden?Intru schreef op zaterdag 05 mei 2012 @ 12:31:
Een nieuw wachtwoord instellen bij de RuG is ook altijd een feest: http://www.rug.nl/medewer...etenswaardigheden?lang=nl
Ze zeggen trouwens niet dat non-printable ASCII characters niet toegestaan zijn, maar ik betwijfel of wachtwoorden met tab of ASCII 0 erin toegestaan zijn.
Gelukkig valt het eerder genoemde wachtwoord van “qqQQ11!!” nog wel gewoon onder de regels. Dan kun je die jaarlijks vervangen door “wwWW22@@”, “eeEE33##”, “rrRR44$$”, enzovoorts. Veilig is anders, maar het is wel makkelijk in te typen én voldoet aan alle eisen!
Hoe zou je het aanpakken zonder plaintext?Verwijderd schreef op zaterdag 05 mei 2012 @ 14:02:
Daar heb je helemaal geen plaintext voor nodig
Als je alleen eist dat het wachtwoord niet letterlijk hetzelfde is als het vorige dan kun je inderdaad met een hash toe. Een aantal andere eisen zijn ook nog wel zonder plaintext te checken. Maar heel algemene eisen (zoals e.g. de edit distance naar een vorig wachtwoord moet minstens 3 zijn) zijn praktisch niet te checken zonder de plain text te hebben.
Simpel:Soultaker schreef op zaterdag 05 mei 2012 @ 14:16:
*snip*
Hoe zou je het aanpakken zonder plaintext?
Als je alleen eist dat het wachtwoord niet letterlijk hetzelfde is als het vorige dan kun je inderdaad met een hash toe. Een aantal andere eisen zijn ook nog wel zonder plaintext te checken. Maar heel algemene eisen (zoals e.g. de edit distance naar een vorig wachtwoord moet minstens 3 zijn) zijn praktisch niet te checken zonder de plain text te hebben.
Typ oud wachtwoord in:
Typ nieuw wachtwoord in:
Herhaal nieuw ww:
Dan controleer je of het oude overeenkomt met de hash, en kijk je of het nieuw genoeg afwijkt van het oude
Verwijderd
wsitedesign schreef op zaterdag 05 mei 2012 @ 14:26:
[...]
Simpel:
Typ oud wachtwoord in:
Typ nieuw wachtwoord in:
Herhaal nieuw ww:
Dan controleer je of het oude overeenkomt met de hash, en kijk je of het nieuw genoeg afwijkt van het oude
Als je je wachtwoord maar 1 letter wijzigt gaat je hash niet "een beetje" aangepast zijn, je krijgt een compleet andere hash.
Ik geloof dat er hier een misverstand is? Tuurlijk dat een hash volledig veranderd bij het wijzigen van 1 letter...Verwijderd schreef op zaterdag 05 mei 2012 @ 15:28:
[...]
![]()
Als je je wachtwoord maar 1 letter wijzigt gaat je hash niet "een beetje" aangepast zijn, je krijgt een compleet andere hash.
Als je huidige wacthwoord gehast opgeslagen is, hoe weet je dan dat een ingevoerd wachtwoord correct is? Juist, je neemt het ingevoerde, hasht het en vergelijkt de hashes. In je applicatie heb je op dat moment dus ook tegelijkertijd de ongehashte versie. Daar kun je dan tegen vergelijken voor het nieuwe wachtwoord
Dat kan inderdaad, maar dat is heel vervelend als de eis is dat (zoals Ragnax zei) het wachtwoord verschilt van alle laatste Y wachtwoorden. (Of je moet de gebruiker z'n laatste Y wachtwoorden laten intypen, wat natuurlijk praktisch ondoenlijk is.)wsitedesign schreef op zaterdag 05 mei 2012 @ 14:26:
Simpel:
Typ oud wachtwoord in:
Typ nieuw wachtwoord in:
Herhaal nieuw ww:
Dan controleer je of het oude overeenkomt met de hash, en kijk je of het nieuw genoeg afwijkt van het oude
Je kan niet volstaan met alleen checken tegen het oude wachtwoorden want dan kun je steeds tussen twee basiswachtwoorden wisselen: "appel1", "appel2" mag niet, "banaan2", "appel3", "banaan4", et cetera.
[ Voor 7% gewijzigd door Soultaker op 05-05-2012 15:41 ]
Ik ging er inderdaad maar vanuit met het vorige wachtwoord, niet met alle vorigeSoultaker schreef op zaterdag 05 mei 2012 @ 15:40:
[...]
Dat kan inderdaad, maar dat is heel vervelend als de eis is dat (zoals Ragnax zei) het wachtwoord verschilt van alle laatste Y wachtwoorden. (Of je moet de gebruiker z'n laatste Y wachtwoorden laten intypen, wat natuurlijk praktisch ondoenlijk is.)
Je kan niet volstaan met alleen checken tegen het oude wachtwoorden want dan kun je steeds tussen twee basiswachtwoorden wisselen: "appel1", "appel2" mag niet, "banaan2", "appel3", "banaan4", et cetera.
In dit geval kun je bijna niet anders dan een symmetrische versleuteling gebruiken, of ... plaintext -_-
Banken en verzekeraars en daar omheen hangende software hebben deze eis. Dus: elke 3 maanden een nieuw wachtwoord, mag niet eerder gebruikt zijn, moet minimaal 10 karakters zijn, hoofletters, kleine letters, cijfers en een leesteken bevatten. En hoe denken die idioten dat een gebruiker dat gaat onthoudenSoultaker schreef op zaterdag 05 mei 2012 @ 15:40:
[...]
Dat kan inderdaad, maar dat is heel vervelend als de eis is dat (zoals Ragnax zei) het wachtwoord verschilt van alle laatste Y wachtwoorden. (Of je moet de gebruiker z'n laatste Y wachtwoorden laten intypen, wat natuurlijk praktisch ondoenlijk is.)
Wat bedoel je precies met een digitaal paspoort?
Voor banken en dergelijke is two-factor authentication de standaard (en terecht) meestal in de vorm van iets dat alleen jij kent (een wachtwoord of pincode) en iets dat alleen jij hebt (een authenticator/dongle ofzoiets, of desnoods een telefoon). Dan moet je er inderdaad voor zorgen dat het wachtwoord geheim blijft, want als mensen 'm op een post-it schrijven en die op hun authenticator plakken dan heb je feitelijk maar één authenticatie-modus over.
(Bij mijn bank heb ik niet eens een gebruikersnaam óf een wachtwoord; alleen een authenticator met m'n gewone pincode. Makkelijk te onthouden.)
edit:
Wachtwoord op een papiertje schrijven heb ik bij DigiD ook gedaan, nadat ik twee keer het unieke wachtwoord dat ik hooguit één keer per jaar nodig heb vergeten was. Dat systeem zou veiliger zijn als SMS-authenticatie verplicht was, maar de wachtwoordeisen minder strikt waren (zodat ik m'n wachtwoord niet hoef op te schrijven).
Voor banken en dergelijke is two-factor authentication de standaard (en terecht) meestal in de vorm van iets dat alleen jij kent (een wachtwoord of pincode) en iets dat alleen jij hebt (een authenticator/dongle ofzoiets, of desnoods een telefoon). Dan moet je er inderdaad voor zorgen dat het wachtwoord geheim blijft, want als mensen 'm op een post-it schrijven en die op hun authenticator plakken dan heb je feitelijk maar één authenticatie-modus over.
(Bij mijn bank heb ik niet eens een gebruikersnaam óf een wachtwoord; alleen een authenticator met m'n gewone pincode. Makkelijk te onthouden.)
edit:
Wachtwoord op een papiertje schrijven heb ik bij DigiD ook gedaan, nadat ik twee keer het unieke wachtwoord dat ik hooguit één keer per jaar nodig heb vergeten was. Dat systeem zou veiliger zijn als SMS-authenticatie verplicht was, maar de wachtwoordeisen minder strikt waren (zodat ik m'n wachtwoord niet hoef op te schrijven).
[ Voor 22% gewijzigd door Soultaker op 05-05-2012 16:13 ]
laat maar...
[ Voor 97% gewijzigd door Marcj op 05-05-2012 16:15 ]
Digitaal paspoort: https://dp.abz.nl/
Banken hebben ook randsystemen om bijvoorbeeld hypotheken aan te kunnen vragen etc.
Banken hebben ook randsystemen om bijvoorbeeld hypotheken aan te kunnen vragen etc.
Het zou me niet verbazen als blijkt dat password-updates via unencoded HTTP GET-requests worden doorgegeven aan andere systemen.Soultaker schreef op zaterdag 05 mei 2012 @ 14:16:
[...]
Urgh. Wat is er zo speciaal aan het & teken dat dát niet gebruikt mag worden?
Denk aan het volgende:
Http://esb/updatePassword.do?user=henk&newPassword=Tr0ub@doUr3$
[ Voor 3% gewijzigd door Alex) op 05-05-2012 16:17 ]
We are shaping the future
Daar hebben we toch urlencode voor?Alex) schreef op zaterdag 05 mei 2012 @ 16:17:
Het zou me niet verbazen als blijkt dat password-updates via unencoded HTTP GET-requests worden doorgegeven aan andere systemen.
Denk aan het volgende:
Http://esb/updatePassword.do?user=henk&newPassword=Tr0ub@doUr3$
If money talks then I'm a mime
If time is money then I'm out of time
Tenzij je de oude wachtwoorden wel weer als tekst gaat opslaan.Soultaker schreef op zaterdag 05 mei 2012 @ 15:40:
[...]
Dat kan inderdaad, maar dat is heel vervelend als de eis is dat (zoals Ragnax zei) het wachtwoord verschilt van alle laatste Y wachtwoorden. (Of je moet de gebruiker z'n laatste Y wachtwoorden laten intypen, wat natuurlijk praktisch ondoenlijk is.)
Je kan niet volstaan met alleen checken tegen het oude wachtwoorden want dan kun je steeds tussen twee basiswachtwoorden wisselen: "appel1", "appel2" mag niet, "banaan2", "appel3", "banaan4", et cetera.
Nadeel dan is eigenlijk dat in veel gevallen van normale gebruikers waarschijnlijk het wachtwoord net zo goed niet gehasht opgeslagen kan worden.
Vorige wachtwoorden: porsche mercedus peugeot volvo renault
Nou, laat ik eens beginnen met wat automerken.
486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22
Verwijderd
Met een beetje algoritme kun je het nieuwe wachtwoord wel testen op de oude hashes. Elk teken een paar bitjes up en down en vergelijken maar. Zo moeilijk is het niet hoor.Verwijderd schreef op zaterdag 05 mei 2012 @ 15:28:
[...]
![]()
Als je je wachtwoord maar 1 letter wijzigt gaat je hash niet "een beetje" aangepast zijn, je krijgt een compleet andere hash.
Dus ik blijf bij mijn stelling: ook voor "nieuw wachtwoord mag niet eerder gebruikt zijn" en "moet minimaal X afwijken" heb je geen plaintext nodig.
[ Voor 14% gewijzigd door Verwijderd op 05-05-2012 21:22 ]
Wat is er dan eigenlijk mis met het opslaan van de laatste X hashes + salts? Als dan het nieuwe ingevoerde wachtwoord overeenkomt met een van die combinaties weet je dus dat er een oud wachtwoord is ingevoerd. En dan heb je de wachtwoorden niet plain-text op te slaan.
C'est le ton qui fait la musique. | Blog | @linkedin
R8 | 18-55 IS | 50mm 1.8 2 | 70-200 2.8 APO EX HSM | 85 1.8
In de categorie "slechte programmeervoorbeelden" kan deze toch niet achter blijven?
https://www.zdnet.com/blo...words-in-clear-text/11963
https://www.zdnet.com/blo...words-in-clear-text/11963
I'm not a complete idiot. Some parts are missing.
.Gertjan.: Ik ben een zelfstandige alcoholist, dus ik bepaal zelf wel wanneer ik aan het bier ga!
Als je wilt testen op een afwijking van één teken misschien nog wel te doen, maar meer dan één is uit combinatorisch oogpunt niet zo'n goed plan...Verwijderd schreef op zaterdag 05 mei 2012 @ 21:18:
[...]
Met een beetje algoritme kun je het nieuwe wachtwoord wel testen op de oude hashes. Elk teken een paar bitjes up en down en vergelijken maar. Zo moeilijk is het niet hoor.
Heeft geen speciale krachten en is daar erg boos over.
Inderdaad, wat een blunder!Firesphere schreef op zondag 06 mei 2012 @ 20:18:
In de categorie "slechte programmeervoorbeelden" kan deze toch niet achter blijven?
https://www.zdnet.com/blo...words-in-clear-text/11963
Met een beetje algoritme is dat juist niet goed te doen.Verwijderd schreef op zaterdag 05 mei 2012 @ 21:18:
[...]
Met een beetje algoritme kun je het nieuwe wachtwoord wel testen op de oude hashes. Elk teken een paar bitjes up en down en vergelijken maar. Zo moeilijk is het niet hoor.
Dus ik blijf bij mijn stelling: ook voor "nieuw wachtwoord mag niet eerder gebruikt zijn" en "moet minimaal X afwijken" heb je geen plaintext nodig.
Als je het echt goed doet gebruik je iets als PBKDF2.
Simpel uitgelegd is het een hashfunctie die altijd in een lusje gedaan wordt.
Dus in geval van sha256 zou je dan bijvoorbeeld sha256(sha256(sha256(sha256(wachtwoord)))) doen, maar dan dus niet 4 keer maar bijvoorbeeld 1000 keer.
Om een keer in te loggen is het namelijk niet erg als de hash berekenen een seconde duurt, maar om bruteforce het password te achterhalen is dan niet meer te doen.
486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22
Tuurlijk dat het dan niet meer te doen is, maar dat is nu toch wel een beetje overkill?PiepPiep schreef op zondag 06 mei 2012 @ 22:06:
[...]
Met een beetje algoritme is dat juist niet goed te doen.
Als je het echt goed doet gebruik je iets als PBKDF2.
Simpel uitgelegd is het een hashfunctie die altijd in een lusje gedaan wordt.
Dus in geval van sha256 zou je dan bijvoorbeeld sha256(sha256(sha256(sha256(wachtwoord)))) doen, maar dan dus niet 4 keer maar bijvoorbeeld 1000 keer.
Om een keer in te loggen is het namelijk niet erg als de hash berekenen een seconde duurt, maar om bruteforce het password te achterhalen is dan niet meer te doen.
Als ik nu een sha512 hash met het wachtwoord en een salt van bijv. registratietijd die ik door de md5 gehaald heb, wordt het imho al redelijk moeilijk om dit nog te reversen of te brute-forcen... Zelfs al achterhaal je de md5 hash die als salt is gebruikt, kun je nog redelijk lang bezig zijn. Voor de meeste sites zal dit imho toch wel volstaan?*
* zeker als je dan weet dat er nog veel zijn die plain-text opslaan, of gewoon md5...
Verwijderd
Deze is ook leuk:
http://www.funkykit.com/c...-flash-drive.html?start=2
...en dat 6!! keer op de pagina.
http://www.funkykit.com/c...-flash-drive.html?start=2
fijn om te weten... Ik draai overigens zonder flash, waarschijnlijk komt het daar door.Got error 28 from storage engine SQL=SELECT advert.* FROM jos_wbadvert AS advert LEFT JOIN jos_wbadvert_client AS client ON client.id = advert.client_id LEFT JOIN jos_wbadvert_idx_menu AS idx_menu ON idx_menu.advert_id = advert.id LEFT JOIN jos_wbadvert_idx_section AS idx_section ON idx_section.advert_id = advert.id LEFT JOIN jos_wbadvert_idx_category AS idx_category ON idx_category.advert_id = advert.id LEFT JOIN jos_wbadvert_idx_content AS idx_content ON idx_content.advert_id = advert.id WHERE advert.group_id = 1 AND advert.published = 1 AND client.published = 1 AND ((advert.date_start = '0000-00-00 00:00:00') OR (advert.date_start <= '2012-05-06')) AND ((advert.date_stop = '0000-00-00 00:00:00') OR (advert.date_stop >= '2012-05-06')) AND ((advert.imptotal = 0) OR (advert.imptotal > advert.impmade)) AND ((idx_menu.menu_id = 0) OR (idx_menu.menu_id = 0)) AND ((idx_section.section_id = 7) OR (idx_section.section_id = 0)) AND ((idx_category.category_id = 55) OR (idx_category.category_id = 0)) AND ((idx_content.content_id = 8480) OR (idx_content.content_id = 0)) GROUP BY advert.id ORDER BY RAND() LIMIT 1There are No Adverts to Display
...en dat 6!! keer op de pagina.
Zelfde fout, en ik draai wel gewoon flash. Sowieso lijkt het me niet logisch dat je zo'n fout krijgt omdat je clientside geen flash hebt.
Van meerdere keren hashen wordt het er niet beter op. Stel dat je voor elke waarde die je er in stopt, slechts 98% (willekeurige waarde) als mogelijke uitvoer kan krijgen. Met een instelling van 17566.5 rondjes (bij een 512 bit hash) zit iedereen mogelijk met dezelfde hash, en kan iedereen met elk willekeurig wachtwoord gewoon inloggen.PiepPiep schreef op zondag 06 mei 2012 @ 22:06:
[...] Dus in geval van sha256 zou je dan bijvoorbeeld sha256(sha256(sha256(sha256(wachtwoord)))) doen, maar dan dus niet 4 keer maar bijvoorbeeld 1000 keer. [...]
Ik kwam laatst de volgende referentie tegen. Met name het een-na-laatste commentaar. Nu kan ik het niet beoordelen, maar ik denk dat je brute-forcen ook niet te klein moet inschatten.wsitedesign schreef op zondag 06 mei 2012 @ 23:28:
[...] of te brute-forcen... [...]
/Edit: @hieronder: Interessant, erg leerzaam. Bedankt hiervoor.
[ Voor 3% gewijzigd door Feanathiel op 08-05-2012 17:39 ]
Ik kwam laatst ook nog error 28 tegen bij een klant van mij omdat zijn HDD vol was gelopen met MySQL queries (als in 1 groot bestand van 60GB).Verwijderd schreef op maandag 07 mei 2012 @ 00:02:
Deze is ook leuk:
http://www.funkykit.com/c...-flash-drive.html?start=2
[...]
fijn om te weten... Ik draai overigens zonder flash, waarschijnlijk komt het daar door.
...en dat 6!! keer op de pagina.
[ Voor 4% gewijzigd door Manuel op 07-05-2012 08:40 ]
Zie Wikipedia: Key stretchingFeanathiel schreef op maandag 07 mei 2012 @ 08:24:
[...]
Van meerdere keren hashen wordt het er niet beter op. Stel dat je voor elke waarde die je er in stopt, slechts 98% (willekeurige waarde) als mogelijke uitvoer kan krijgen. Met een instelling van 17566.5 rondjes (bij een 512 bit hash) zit iedereen mogelijk met dezelfde hash, en kan iedereen met elk willekeurig wachtwoord gewoon inloggen.
FPGA's zijn fantastische stukjes techniek. Wij baseren onze video-analyse en conversie-apparatuur ook op FPGA's. Nog een stukje rapper en groter dan de gene beschreven in het artikel.Feanathiel schreef op maandag 07 mei 2012 @ 08:24:
Ik kwam laatst de volgende referentie tegen. Met name het een-na-laatste commentaar. Nu kan ik het niet beoordelen, maar ik denk dat je brute-forcen ook niet te klein moet inschatten.
Wat ik overigens doe om (in PHP) de wachtwoorden op te slaan:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| private function validate_password($password) { $salt = substr($this->hashed_password, 0, 64); $hash = substr($this->hashed_password, 64, 64); $password_hash = hash('sha256', $salt . $password); return $password_hash == $hash; } private function hash_password($password) { $salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); $hash = hash('sha256', $salt . $password); return $salt . $hash; } |
SHA256, maar een keer gehashed om de kans op collisions zo klein mogelijk te houden. Al is de kans op collisions bij een SHA256 al niet bijster groot.
Edit; Ik weet niet of bovenstaande het topic waardig is
If money talks then I'm a mime
If time is money then I'm out of time
Ojee, hashes. Nou moet ik weer posten 
Stel:
Gebruik je iets zwaarders (zoals PiepPiep's suggestie), dan wordt het compleet onhaalbaar.


(let op, md5 is doorgaans ook gesalt, bij PHP bijvoorbeeld standaard met een 12-character salt)
(disclaimer: ik juich elke migratie van MD5 naar iets beters toe! Ik wil alleen wel graag dat zaken in de juiste verhouding gezien worden)
Maar dat gezegd vind ik wel dat er het een en ander af te dingen is op zijn verhaal, met name op de prijs/performance conclusie. Hij gaat uit van 2 hashes/clock (klinkt acceptabel met een goed design) en 50MHz (klinkt ook acceptabel). Dat komt neer op 100 Mhash/sec. De vraag is dan wat de FPGA in kwestie kost, die dingen varieren van 10 tot 1000+ euro per stuk afhankelijk van de specificaties. Om tot leuke getallen te komen gebruikt hij 64 FPGAs (en stelt vervolgens weer voor om blokken van 64 FPGAs te stapelen).
Iemand die een FPGA MD5 cracker als afstudeerproject heeft gedaan haalde nog geen 1 Mhash/sec op een Altera II 2C35, welke rond de $100 kost. Ter vergelijking, mijn computer (Core 2 duo) heb ik tweedehands gekocht voor €75 en doet 4 Mhash/sec.
Maar laten we onze comment-poster het voordeel van de twijfel geven, en zeggen dat hij zijn 100 Mhash/sec haalt op een FPGA van €10, ongeveer 1000 keer zo snel/goedkoop als die student dus. Dan doet hij 10 Mhash/sec/euro, tegenover 0.05 Mhash/sec/euro voor mijn PC. 200 keer zo goedkoop/snel dus.
Is dat sneller? Sure. Is dat snel genoeg om te beweren dat rainbow tables geen realistische aanval zijn? Nee.
Stel we hebben een dictionary van 50 miljoen wachtwoorden (en variaties). De FPGA van meneer doet er een halve seconde over om een hash te testen tegen die dictionary. Een rainbow table voor deze dictionary is ongeveer 1.5GB. Een binary search naar de juiste hash kost maximaal 26 lookups (en dat kan slimmer, gezien de uniformiteit). Als één lookup op mijn computer 100ns kost, dan kost het doorzoeken van de rainbow table ongeveer 2.5µs, 200 000 keer zo snel brute force als op de FPGA. Koop duizend FPGAs, en mijn rainbow table is nog steeds 200 keer zo snel.
En dat is onder de aanname dat je die dictionary efficient op je FPGA krijgt... Met 100 Mhash/sec en 8-byte wachtwoorden moet je al continue 800 MB/sec aan je FPGA voeren. Dat kan nog wel eens problematisch worden voor goedkope FPGAs. Je kunt natuurlijk de FPGA wel de hele mogelijke wachtwoordruimte laten doorzoeken, maar die ruimte is vele malen groter dan zo'n dictionary, dus daar neemt de rekentijd gigantisch mee toe.
Conclusie: FPGAs zijn inderdaad leuk speelgoed, en als je op grote schaal wachtwoordhashes kraakt kunnen ze erg aantrekkelijk zijn. Maar ze zijn niet heilig, en maken salts zeker niet nutteloos.
Conclusie 2: gebruik de duurste hash die je acceptabel kunt gebruiken (dat is dus minimaal SHA256), en gebruik een random salt van degelijke grootte.
Dan vind ik dat je beter een mailtje met een activatie-link kunt sturen. Dat is feitelijk natuurlijk hetzelfde, maar duidelijker voor gebruikers; anders heb je "magische eenmalige eerstekeer-wachtwoorden" en "echte wachtwoorden"..Gertjan. schreef op maandag 30 april 2012 @ 21:52:
Uiteraard is het dan nog niet helemaal veilig (het "geheim" staat namelijk ergens als plain-text opgeslagen, namelijk in iemands mailbox en heeft diverse stations gepasseerd waar men het zou kunnen zien), maar daar zijn dan weer trucjes als "user must change password on first logon" voor uitgevonden
Dat hangt nogal van de context af natuurlijk.Verwijderd schreef op zaterdag 05 mei 2012 @ 21:18:
Met een beetje algoritme kun je het nieuwe wachtwoord wel testen op de oude hashes. Elk teken een paar bitjes up en down en vergelijken maar. Zo moeilijk is het niet hoor.
Dus ik blijf bij mijn stelling: ook voor "nieuw wachtwoord mag niet eerder gebruikt zijn" en "moet minimaal X afwijken" heb je geen plaintext nodig.
Stel:
- Toegestane tekens zijn alle non-control chars van US ASCII (Zo'n beetje alles wat je standaard met een US QWERY toetsenbord kunt maken, 95 tekens).
- Je wil een edit-distance van 3 of korter niet toestaan.
- De gebruiker voert een nieuw wachtwoord van 10 tekens in.
Gebruik je iets zwaarders (zoals PiepPiep's suggestie), dan wordt het compleet onhaalbaar.
Waarom? Het herhalen van een hash zorgt ervoor dat de hash berekenen trager wordt, zodat brute-forcen onaantrekkelijk wordt. Natuurlijk kun je dat overkill vinden, maar tsja... Je kunt überhaupt hashen ook overkill vinden. Waar trek je die grens?wsitedesign schreef op zondag 06 mei 2012 @ 23:28:
Tuurlijk dat het dan niet meer te doen is, maar dat is nu toch wel een beetje overkill?
...dan heb je een slechte salt. Gebruik alsjeblieft gewoon een random string.Als ik nu een sha512 hash met het wachtwoord en een salt van bijv. registratietijd die ik door de md5 gehaald heb...
Natuurlijk achterhaal je die, een salt is onderdeel van een hash.Zelfs al achterhaal je de md5 hash die als salt is gebruikt
Hoeveel onveiliger denk je dat "gewoon md5" is dan jouw geschetste aanpak?* zeker als je dan weet dat er nog veel zijn die plain-text opslaan, of gewoon md5...
(let op, md5 is doorgaans ook gesalt, bij PHP bijvoorbeeld standaard met een 12-character salt)
(disclaimer: ik juich elke migratie van MD5 naar iets beters toe! Ik wil alleen wel graag dat zaken in de juiste verhouding gezien worden)
offtopic:
Over PHP gesproken trouwens:
PHP crypt() - Return Values: Returns the hashed string or a string that is shorter than 13 characters and is guaranteed to differ from the salt on failure.
Ugh
Over PHP gesproken trouwens:
PHP crypt() - Return Values: Returns the hashed string or a string that is shorter than 13 characters and is guaranteed to differ from the salt on failure.
Ugh
Die comment lijkt te willen concluderen dat je beter geen salts dan wel salts kunt gebruiken, en dat is sowieso onzin; zelfs al helpt een salt je niet (en dat doet een salt idd niet bij brute force; salts helpen tegen precomputed dictionary attacks), kwaad doet een salt niet. Hij stipt wel goed aan wat één van de redenen is dat MD5 tegenwoordig af te raden is; de hash is gewoon te licht aan het worden voor het rekengeweld van tegenwoordig.Feanathiel schreef op maandag 07 mei 2012 @ 08:24:
Ik kwam laatst de volgende referentie tegen. Met name het een-na-laatste commentaar. Nu kan ik het niet beoordelen, maar ik denk dat je brute-forcen ook niet te klein moet inschatten.
Maar dat gezegd vind ik wel dat er het een en ander af te dingen is op zijn verhaal, met name op de prijs/performance conclusie. Hij gaat uit van 2 hashes/clock (klinkt acceptabel met een goed design) en 50MHz (klinkt ook acceptabel). Dat komt neer op 100 Mhash/sec. De vraag is dan wat de FPGA in kwestie kost, die dingen varieren van 10 tot 1000+ euro per stuk afhankelijk van de specificaties. Om tot leuke getallen te komen gebruikt hij 64 FPGAs (en stelt vervolgens weer voor om blokken van 64 FPGAs te stapelen).
Iemand die een FPGA MD5 cracker als afstudeerproject heeft gedaan haalde nog geen 1 Mhash/sec op een Altera II 2C35, welke rond de $100 kost. Ter vergelijking, mijn computer (Core 2 duo) heb ik tweedehands gekocht voor €75 en doet 4 Mhash/sec.
Maar laten we onze comment-poster het voordeel van de twijfel geven, en zeggen dat hij zijn 100 Mhash/sec haalt op een FPGA van €10, ongeveer 1000 keer zo snel/goedkoop als die student dus. Dan doet hij 10 Mhash/sec/euro, tegenover 0.05 Mhash/sec/euro voor mijn PC. 200 keer zo goedkoop/snel dus.
Is dat sneller? Sure. Is dat snel genoeg om te beweren dat rainbow tables geen realistische aanval zijn? Nee.
Stel we hebben een dictionary van 50 miljoen wachtwoorden (en variaties). De FPGA van meneer doet er een halve seconde over om een hash te testen tegen die dictionary. Een rainbow table voor deze dictionary is ongeveer 1.5GB. Een binary search naar de juiste hash kost maximaal 26 lookups (en dat kan slimmer, gezien de uniformiteit). Als één lookup op mijn computer 100ns kost, dan kost het doorzoeken van de rainbow table ongeveer 2.5µs, 200 000 keer zo snel brute force als op de FPGA. Koop duizend FPGAs, en mijn rainbow table is nog steeds 200 keer zo snel.
En dat is onder de aanname dat je die dictionary efficient op je FPGA krijgt... Met 100 Mhash/sec en 8-byte wachtwoorden moet je al continue 800 MB/sec aan je FPGA voeren. Dat kan nog wel eens problematisch worden voor goedkope FPGAs. Je kunt natuurlijk de FPGA wel de hele mogelijke wachtwoordruimte laten doorzoeken, maar die ruimte is vele malen groter dan zo'n dictionary, dus daar neemt de rekentijd gigantisch mee toe.
Conclusie: FPGAs zijn inderdaad leuk speelgoed, en als je op grote schaal wachtwoordhashes kraakt kunnen ze erg aantrekkelijk zijn. Maar ze zijn niet heilig, en maken salts zeker niet nutteloos.
Conclusie 2: gebruik de duurste hash die je acceptabel kunt gebruiken (dat is dus minimaal SHA256), en gebruik een random salt van degelijke grootte.
De grens trek ik waar je het een potentiele hacker al een stuk moeilijker maakt dan dat het nodig is. Als ze met een "simpele" md5 of sha1 (waar er genoeg reverse-hash sites voor zijn) gehasht zijn (zonder salts), maak je het een hacker niet veel moeilijker dan plain-text. Een sha-512 met (goedgekozen) salt zou het al een stuk moeilijker zijn, dus dat is mijn persoonlijke grens.deadinspace schreef op maandag 07 mei 2012 @ 11:24:
Waarom? Het herhalen van een hash zorgt ervoor dat de hash berekenen trager wordt, zodat brute-forcen onaantrekkelijk wordt. Natuurlijk kun je dat overkill vinden, maar tsja... Je kunt überhaupt hashen ook overkill vinden. Waar trek je die grens?
Ok dan... Hier heb je een sha-512 met de salt ertussen, waar zit de salt?deadinspace schreef op maandag 07 mei 2012 @ 11:24:
...dan heb je een slechte salt. Gebruik alsjeblieft gewoon een random string.
Als je als hacker dan de broncode niet kunt bemachtigen, kun je dit niet weten en is dit dus imho veilig.
c8723ae7e41f9c756627f929fc3a3d56cc872d2fc4af5a4b3759ea6ca8c7dbf1098f6bcd4621d373cade4e832627b4f692000c36287bc6b8b0b0c986b7fb3f3ef1aa685e7b12d942a8c1616f0796dac1
(en stel dat je zelfs nog niet weet dat er hier een gedeelte sha-512 is, heb je nog meer keuzes
Zie mijn punt hierboven.deadinspace schreef op maandag 07 mei 2012 @ 11:24:
Natuurlijk achterhaal je die, een salt is onderdeel van een hash.
Redelijk veel onveiliger, zie hierboven ook alweerdeadinspace schreef op maandag 07 mei 2012 @ 11:24:
Hoeveel onveiliger denk je dat "gewoon md5" is dan jouw geschetste aanpak?
Wie gebruikt er dan crypt() voor MD5? De meeste mensen doen dat met md5()deadinspace schreef op maandag 07 mei 2012 @ 11:24:
(let op, md5 is doorgaans ook gesalt, bij PHP bijvoorbeeld standaard met een 12-character salt)
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Je kan toch alle letters extracten en in sequence hashen en opslaan en alle niet-letters extracten en in sequence hashen. Dit zelfde doe je met het nieuwe wachtwoord, als je dan een match hebt op een van de twee is het niet verschillend genoeg. Niet perfect, maar dan heb je een semi-usage check zonder unencrypted spul op te slaan.PiepPiep schreef op zaterdag 05 mei 2012 @ 20:44:
[...]
Tenzij je de oude wachtwoorden wel weer als tekst gaat opslaan.
Nadeel dan is eigenlijk dat in veel gevallen van normale gebruikers waarschijnlijk het wachtwoord net zo goed niet gehasht opgeslagen kan worden.
Vorige wachtwoorden: porsche mercedus peugeot volvo renault
Nou, laat ik eens beginnen met wat automerken.
De originele developer van een project van ons deed dat. Toen we erachter kwamen dat alle strings langer dan 8 karakters met dezelfde salt, allemaal dezelfde hash gaven, hebben we dat maar veranderd naar een ander algoritme (met ook nog eens unieke salts).oisyn schreef op maandag 07 mei 2012 @ 12:17:
[...]
Wie gebruikt er dan crypt() voor MD5? De meeste mensen doen dat met md5()
Zit wat in, maar vraag jezelf eens af waarom je het ze niet nóg moeilijker zou maken, als dat niet veel werk kost.wsitedesign schreef op maandag 07 mei 2012 @ 11:58:
[...]
De grens trek ik waar je het een potentiele hacker al een stuk moeilijker maakt dan dat het nodig is. Als ze met een "simpele" md5 of sha1 (waar er genoeg reverse-hash sites voor zijn) gehasht zijn (zonder salts), maak je het een hacker niet veel moeilijker dan plain-text. Een sha-512 met (goedgekozen) salt zou het al een stuk moeilijker zijn, dus dat is mijn persoonlijke grens.
Ah, security through obscurity. Het punt was ook dat de registratietijd geen goed idee is om te gebruiken, voor redenen kijk bijvoorbeeld eens hier.[...]
Ok dan... Hier heb je een sha-512 met de salt ertussen, waar zit de salt?
Als je als hacker dan de broncode niet kunt bemachtigen, kun je dit niet weten en is dit dus imho veilig.
c8723ae7e41f9c756627f929fc3a3d56cc872d2fc4af5a4b3759ea6ca8c7dbf1098f6bcd4621d373cade4e832627b4f692000c36287bc6b8b0b0c986b7fb3f3ef1aa685e7b12d942a8c1616f0796dac1
(en stel dat je zelfs nog niet weet dat er hier een gedeelte sha-512 is, heb je nog meer keuzes)
Nu denk je natuurlijk: Maar dat is toch nog een redelijk verwaarloosbaar risico? Het is toch maar een héél klein ietsiepietsie beetje onveiliger? Klopt. Maar waarom zou je, aangezien het je niet tot nauwelijks extra moeite kost, het niet gewoon dat kleine beetje veiliger maken?
Les één uit cryptografie: neem altijd aan dat de aanvaller weet hoe je systeem ontworpen is (en dat is echt les één). Ga er bij wachtwoorden dus van uit dat ze de gebruikte structuur weten, maar de keuzes binnen die structuur niet. Voor hashes hetzelfde, ga er van uit dat ze de structuur weten. Al het andere is security by obscurity.wsitedesign schreef op maandag 07 mei 2012 @ 11:58:
Als je als hacker dan de broncode niet kunt bemachtigen, kun je dit niet weten en is dit dus imho veilig.
Om het concreter te maken: als ze de hashes uit je DB weten te vissen, waarom ben je dan zo arrogant te denken dat ze je broncode niet kunnen zien?
Waarom denk je dat het standaard-hashformaat $id$salt$hash is? Omdat het zin heeft de salt te verstoppen? Of omdat dat juist geen zin heeft?
Zie hierboven wat?Redelijk veel onveiliger, zie hierboven ook alweer
En ik waag het te betwisten. Bij een MD5-hash met degelijke salt is brute forcen je enige optie, en crypt() doet aan key stretching, wat het bruteforcen daarvan trager zal maken dan een naive sha512-aanpak.
Al met al zou MD5 crypt() met een 72-bit salt paradoxaal genoeg veiliger kunnen zijn dan jouw geschetste aanpak (ervanuitgaande dat je geen crypt() gebruikt, maar gezien je geklooi met salts zal dat wel niet).
Merk op dat ik niet het gebruik van MD5 wil goedpraten; MD5 moet dood, en SHA512 lijkt een waardige opvolger te zijn. Maar verneuk je keuze van een goed hash-algoritme niet door andere dingen te verklooien. Gebruik de kennis van mensen die wel thuis zijn in cryptografie. Neem nou maar aan dat je voor salts echt een random string moet nemen. Gebruik nou maar gewoon crypt(), die doet onder andere key stretching voor je. Neem aan dat een aanvaller alle gebruikte parameters weet, behalve het wachtwoord zelf.
Is dat zo? Ik heb nog nooit md5()-gebruik voor wachtwoordhashes gezien. Mja, anekdotaal bewijs....oisyn schreef op maandag 07 mei 2012 @ 12:17:
Wie gebruikt er dan crypt() voor MD5? De meeste mensen doen dat met md5()
In ieder geval is dat een domme keuze van de meeste mensen dan. crypt() regelt de salt voor je, ondersteunt meerdere algoritmen (zoals ook SHA256 en SHA512) zodat migreren makkelijk is, en crypt() doet key stretching (zo'n 1000 iteraties voor MD5) voor je om brute forcen minder praktisch te maken.
Ja, dan heeft hij crypt() DES-hashes laten genereren. Dat dan alleen de eerste 8 tekens significant zijn is gewoon gedocumenteerd.Tsunami schreef op maandag 07 mei 2012 @ 15:04:
De originele developer van een project van ons deed dat. Toen we erachter kwamen dat alle strings langer dan 8 karakters met dezelfde salt, allemaal dezelfde hash gaven, hebben we dat maar veranderd naar een ander algoritme (met ook nog eens unieke salts)
Toegegeven, DES password-hashing is tegenwoordig braindead te beschouwen en zou niet meer mogen bestaan, en crypt() is een kut-interface, maar dat probleem was gewoon te voorkomen geweest door braaf de documentatie te lezen
Je hebt natuurlijk wel gelijk, maar ik bedoel vooral:Patriot schreef op maandag 07 mei 2012 @ 18:26:
[...]
Zit wat in, maar vraag jezelf eens af waarom je het ze niet nóg moeilijker zou maken, als dat niet veel werk kost.
[...]
Ah, security through obscurity. Het punt was ook dat de registratietijd geen goed idee is om te gebruiken, voor redenen kijk bijvoorbeeld eens hier.
Nu denk je natuurlijk: Maar dat is toch nog een redelijk verwaarloosbaar risico? Het is toch maar een héél klein ietsiepietsie beetje onveiliger? Klopt. Maar waarom zou je, aangezien het je niet tot nauwelijks extra moeite kost, het niet gewoon dat kleine beetje veiliger maken?
als een hacker die op een of andere manier gewoon in mijn DB binnengeraakt nu die hashes zie, hoe kan hij dan in godsnaam weten hoe het in elkaar zit? Veel kans dat hij gewoon opgeeft. Als je natuurlijk "insider" info hebt, kun je iets doen, maar de meeste hackers gaan zover niet (zeker skiddies niet)
Anyway, mijn methode om te registreren/gebruikers toe te voegen is toch nog niet gemaakt, dus ik kan deze nog naar hartelust aanpassen, zal dit dan ook doen met een random salt in het achterhoofd
PS: het was uiteindelijk: sha-512("test".md5("test")), dan in 2 splitsen en de md5 ertussen plaatsen ^^
Omdat er nu eenmaal sneller een sql-injectie kan gebeuren dan de volledige broncode kapen denk ik? Natuurlijk is het altijd mogelijk, maar dan kan je evengoed een extra regel code met email met plaintext wachtwoord toevoegen...deadinspace schreef op maandag 07 mei 2012 @ 18:27:
*snip*
Om het concreter te maken: als ze de hashes uit je DB weten te vissen, waarom ben je dan zo arrogant te denken dat ze je broncode niet kunnen zien?
*snip*
Sowieso, op dit moment is het nog maar testen, heb dus het registreren nog niet afgewerkt, dus nog tijd zat om het op een betere manier te doen
Edit:
Heb het snel eens nagekeken, op dit moment is het een aanroep naar de hash() functie van php.
@deadinspace: bedankt voor de uitleg... Bijleren is ook altijd interessant. Die disclaimer staat er niets voor niets trouwens
[ Voor 22% gewijzigd door azerty op 07-05-2012 20:15 ]
Klopt, ik vond het ook gewoon netjes terug in de documentatie, dus geen idee waarom hij dat zo had gedaan.deadinspace schreef op maandag 07 mei 2012 @ 18:27:
Toegegeven, DES password-hashing is tegenwoordig braindead te beschouwen en zou niet meer mogen bestaan, en crypt() is een kut-interface, maar dat probleem was gewoon te voorkomen geweest door braaf de documentatie te lezen
Verwijderd
Open Source is ook niet heilig
Vandaag was ik op zoek naar een programma op iWork .pages bestanden te converteren. Toen kwam ik op dit leuke programmatje:
http://sourceforge.net/projects/pagesconvert/
Het is een Windows programma dat duidelijk in een .NET taal gescrheven is (na even zoeken op de site zie ik dat het VB is) wat opzich vreemd is, gezien Pages alleen op OSX / iOS beschikbaar is. Maar goed, mocht je een pages document op Windows willen openen, dan moet het oké zijn.

Redelijke ingewikkelde instructies, maar oké. Ik klik op Browse... En ik sluit het common dialog. Staat er ineens deze tekst in het tekstveld:
1. Het tekstveld is voor bestandsnamen.
2. Het past niet in het tekstveld.
3. Dit is geen nette notificatie.
4. Ik heb op Annuleren geklikt, dat is geen fout.
Echter wordt ook het Convert knopje actief wat ervoor zorgt dat we een mooie exception te zien krijgt. Welke niet afgevangen is.
Dus ja, dan kijken we naar de source. Wacht die staat niet online, het was toch een Open Source project???
Nou ja, Reflector dan maar.
In de frmMain klasse vinden we het standaard WinDesigner spul en twee methodes die alles doen. Meer zit er niet in de applicatie.
Method 1
Au.
1. De filename willen we in txtLocation zien, dus dan is de extra Dim fileName overbodig.
2. OpenFileDialog returned een enum, welke naast OK ook een Cancel kent waarna de methode netjes afgebroken dient te worden.
3. Na het afhandelen van de "fout" wordt alsnog btnConvert enabled..
en dan vooral dit:
Dit levert natuurlijk niet altijd een unieke bestandsnaam op (wat hier gewenst is)
http://sourceforge.net/projects/pagesconvert/
Het is een Windows programma dat duidelijk in een .NET taal gescrheven is (na even zoeken op de site zie ik dat het VB is) wat opzich vreemd is, gezien Pages alleen op OSX / iOS beschikbaar is. Maar goed, mocht je een pages document op Windows willen openen, dan moet het oké zijn.

Redelijke ingewikkelde instructies, maar oké. Ik klik op Browse... En ik sluit het common dialog. Staat er ineens deze tekst in het tekstveld:
Nou hier zijn sowieso al 4 dingen mis mee:ERROR! Type in the file location manually, then hit convert.
1. Het tekstveld is voor bestandsnamen.
2. Het past niet in het tekstveld.
3. Dit is geen nette notificatie.
4. Ik heb op Annuleren geklikt, dat is geen fout.
Echter wordt ook het Convert knopje actief wat ervoor zorgt dat we een mooie exception te zien krijgt. Welke niet afgevangen is.
Dus ja, dan kijken we naar de source. Wacht die staat niet online, het was toch een Open Source project???
Nou ja, Reflector dan maar.
In de frmMain klasse vinden we het standaard WinDesigner spul en twee methodes die alles doen. Meer zit er niet in de applicatie.
Method 1
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
| Private Sub btnBrowse_Click(ByVal sender As Object, ByVal e As EventArgs) Dim dialog As New OpenFileDialog Dim fileName As String = "" dialog.Filter = "XML files (*.xml)|*.xml" If (dialog.ShowDialog = DialogResult.OK) Then fileName = dialog.FileName End If If (fileName.Trim = "") Then fileName = "ERROR! Type in the file location manually, then hit convert." End If Me.txtLocation.Text = fileName Me.btnConvert.Enabled = True End Sub |
Au.
1. De filename willen we in txtLocation zien, dus dan is de extra Dim fileName overbodig.
2. OpenFileDialog returned een enum, welke naast OK ook een Cancel kent waarna de methode netjes afgebroken dient te worden.
3. Na het afhandelen van de "fout" wordt alsnog btnConvert enabled..
Visual Basic .NET:
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
| Private Sub btnConvert_Click(ByVal sender As Object, ByVal e As EventArgs) Dim writer As StreamWriter Dim reader As New StreamReader(Me.txtLocation.Text) If File.Exists(Me.txtLocation.Text.Replace(".xml", ".txt")) Then VBMath.Randomize Dim num3 As Integer = CInt(Math.Round(CDbl(((88888! * VBMath.Rnd) + 1!)))) writer = New StreamWriter(Me.txtLocation.Text.Replace(".xml", (Conversions.ToString(num3) & ".txt"))) Else writer = New StreamWriter(Me.txtLocation.Text.Replace(".xml", ".txt")) End If Dim str As String = reader.ReadToEnd Dim num2 As Integer = Strings.InStr(str, "sf:anchor-loc=""0""", CompareMethod.Binary) str = str.Remove(0, (num2 + &H12)) num2 = Strings.InStr(str, "</sf:layout>", CompareMethod.Binary) str = str.Remove((num2 - 1), (str.Length - num2)).Replace("<sf:br/>", ChrW(13) & ChrW(10)).Replace("<sf:tab/>", ChrW(9)).Replace("<sf:lnbr/>", ChrW(13) & ChrW(10)).Replace("’", "'").Replace("‘", "'").Replace("“", """").Replace("”", """").Replace("ō", "o").Replace("—", "-").Replace("ē", "e").Replace("…", "...").Replace("ï", "i").Replace("ë", "e") num2 = Strings.InStr(str, "<", CompareMethod.Binary) Dim i As Integer = Strings.InStr(str, ">", CompareMethod.Binary) Do While (num2 <> 0) str = str.Remove((num2 - 1), ((i - num2) + 1)) num2 = Strings.InStr(str, "<", CompareMethod.Binary) i = Strings.InStr(str, ">", CompareMethod.Binary) Loop reader.Close writer.Write(str) writer.Close MessageBox.Show("File has been sucessfully converted to .txt.", "Pages Converter") Me.txtLocation.Text = "" Me.btnConvert.Enabled = False End Sub |
en dan vooral dit:
Visual Basic .NET:
1
2
3
| VBMath.Randomize Dim num3 As Integer = CInt(Math.Round(CDbl(((88888! * VBMath.Rnd) + 1!)))) writer = New StreamWriter(Me.txtLocation.Text.Replace(".xml", (Conversions.ToString(num3) & ".txt"))) |
Dit levert natuurlijk niet altijd een unieke bestandsnaam op (wat hier gewenst is)
Bril nodig?Verwijderd schreef op woensdag 09 mei 2012 @ 15:52:
Dus ja, dan kijken we naar de source. Wacht die staat niet online, het was toch een Open Source project???
En niet dat 't veel beter is (
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| Private Sub AddFile() Dim opnFile As New OpenFileDialog Dim strLocation As String '''''''''''''''Filter out all but XML files opnFile.Filter = "XML files (*.xml)|*.xml" '''''''''''''''Show Open Dialog, add to lstLocation If opnFile.ShowDialog() = Windows.Forms.DialogResult.OK Then strLocation = opnFile.FileName '''''''''''''''Quick check for proper file format If Not ((strLocation.IndexOf(".xml") = -1) Or (strLocation.Length < 4)) Then Me.lstLocation.Items.Add(strLocation) Me.btnConvert.Enabled = True End If End If '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' End Sub |
Visual Basic .NET:
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
| Private Sub Convert() Dim strFileContents, strLocation, strFilename As String Dim intIndex, intChars As Integer Dim blnWorkDone As Boolean Do While Not System.IO.File.Exists(Me.lstLocation.Items.Item(0)) 'If file doesn't exist, throw error and remove MessageBox.Show("The file: " & vbCrLf & lstLocation.Items.Item(0) & vbCrLf & "does not exist. It will not be converted.", "Error!") Me.lstLocation.Items.RemoveAt(0) If Me.lstLocation.Items.Count = 0 Then '''''''''''''''Quit loop if nothing is left Exit Do End If Loop Do While Me.lstLocation.Items.Count <> 0 Dim objReader As System.IO.StreamReader = New StreamReader(String.Format(Me.lstLocation.Items.Item(0))) Dim objWriter As System.IO.StreamWriter '''''''''''''''The loop is being run; work must be occuring blnWorkDone = True '''''''''''''''Differentiate path into location and filename for saving document as "filename".txt strFilename = Me.lstLocation.Items.Item(0) strFilename = strFilename.Substring(0, strFilename.LastIndexOf("\")) strFilename = strFilename.Substring(strFilename.LastIndexOf("\") + 1) strFilename = strFilename.Replace(".pages", Nothing) strLocation = String.Format(Me.lstLocation.Items.Item(0)) strLocation = strLocation.Replace("index.xml", strFilename & ".txt") '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''If file exists, add random number. If Not System.IO.File.Exists(strLocation) Then objWriter = New StreamWriter(strLocation) Else Randomize() Dim intRand As Integer = ((99999 - 11111) * Rnd() + 1) objWriter = New StreamWriter(strLocation.Replace(".txt", intRand & ".txt")) End If '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''Read file into string strFileContents = objReader.ReadToEnd '''''''''''''''Remove beginning intIndex = InStr(strFileContents, "sf:anchor-loc=" & """" & "0" & """") strFileContents = strFileContents.Remove(0, intIndex + 18) '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''Remove end intIndex = InStr(strFileContents, "</sf:layout>") strFileContents = strFileContents.Remove(intIndex - 1, (strFileContents.Length) - intIndex) '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''Formatting - this is all I know, feel free to add here strFileContents = strFileContents.Replace("<sf:br/>", vbCrLf) strFileContents = strFileContents.Replace("<sf:tab/>", vbTab) strFileContents = strFileContents.Replace("<sf:lnbr/>", vbCrLf) strFileContents = strFileContents.Replace("’", "'") strFileContents = strFileContents.Replace("‘", "'") strFileContents = strFileContents.Replace("“", """") strFileContents = strFileContents.Replace("”", """") strFileContents = strFileContents.Replace("ō", "o") strFileContents = strFileContents.Replace("—", "-") strFileContents = strFileContents.Replace("ē", "e") strFileContents = strFileContents.Replace("…", "...") strFileContents = strFileContents.Replace("ï", "i") strFileContents = strFileContents.Replace("ë", "e") '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''Gets the variables ready so they aren't forced into the loop (in case no formatting exists) intIndex = InStr(strFileContents, "<") intChars = InStr(strFileContents, ">") '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''Removes all unknown xml While intIndex <> 0 strFileContents = strFileContents.Remove(intIndex - 1, (intChars - intIndex) + 1) intIndex = InStr(strFileContents, "<") ' i forsee this being a problem if someone has < or > in their work. intChars = InStr(strFileContents, ">") End While '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''Close reader, write, close writer objReader.Close() objWriter.Write(strFileContents) objWriter.Close() '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''Remove the item just done Me.lstLocation.Items.RemoveAt(0) Loop '''''''''''''''After everything is done the convert button will need to be disabled and user needs to be alerted If blnWorkDone Then Me.btnConvert.Enabled = False blnWorkDone = False MessageBox.Show("File Conversion Completed." & vbCrLf & vbCrLf & "Files are located in their respective directories", "File Conversion Complete!") End If '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' End Sub |
Je hebt de 0.5 gedownload terwijl er een 0.6 beschikbaar is.
[ Voor 90% gewijzigd door RobIII op 09-05-2012 16:18 ]
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
Verwijderd
Hmm, dan is er een verschil tussen de versie op de homepage en die 0.6 versie
Ze hebben iig mijn opmerkingen gefixed (onder Browse, het converteren is nog steeds brak)
De code die ik gevonden had zit idd in de .5 versie:
http://sourceforge.net/pr...Pages%20Converter%20v0.5/
De code die ik gevonden had zit idd in de .5 versie:
http://sourceforge.net/pr...Pages%20Converter%20v0.5/
[ Voor 46% gewijzigd door Verwijderd op 09-05-2012 16:25 ]
Gelukkig is die versie pas 4 jaar uit 
(Ah vooruit, de website verwijst naar de oude versie, ook faal)
(Ah vooruit, de website verwijst naar de oude versie, ook faal)
[ Voor 44% gewijzigd door Barryvdh op 09-05-2012 16:32 ]
Verwijderd
Want 1 van de verschillende xml parsers van .NET gebruiken is voor noobsRobIII schreef op woensdag 09 mei 2012 @ 16:11:
[...]
En niet dat 't veel beter is ( ), maar ik zie hele andere code:
Dan vooral deze:
code:
1
2
| strFileContents = strFileContents.Replace("ï", "i")
strFileContents = strFileContents.Replace("ë", "e") |
We don't need no frikkin' unicode, ascii slaat gemakkelijker op!
Wie submit hem op tdwtf?
[ Voor 47% gewijzigd door Verwijderd op 09-05-2012 17:40 ]
Ik heb in een van m'n scripts het volgende:
Vraag me niet meer waarom, maar ik weet dat het echt een reden had
PowerShell:
1
| $zero = 0 |
Vraag me niet meer waarom, maar ik weet dat het echt een reden had
[ Voor 5% gewijzigd door YellowOnline op 09-05-2012 18:53 ]
Je kan dan ook 0 gaan randommizen 
$zero = rand()-rand();
$zero = rand()-rand();
No trees were harmed in creating this message. However, a large number of electrons were terribly inconvenienced.
Ow god praat me er niet van, leuk geintje van collega van me...Freeaqingme schreef op woensdag 09 mei 2012 @ 19:07:
Je kan dan ook 0 gaan randommizen
$zero = rand()-rand();
PHP:
1
| function resetToZero($var){ $var = rand(); return $var } |
Diep verstopt in de krochten van een oude half PHP4, half PHP5 applicatie... En "niemand" snapte hoe het kon dat klanten van de webshop willekeurige bedragen opgeteld kregen bij hun bestelling! (gelukkig alleen in testmode, maar toch...)
[ Voor 2% gewijzigd door Firesphere op 09-05-2012 19:20 . Reden: $var dus, PINDA die ik ben! ]
I'm not a complete idiot. Some parts are missing.
.Gertjan.: Ik ben een zelfstandige alcoholist, dus ik bepaal zelf wel wanneer ik aan het bier ga!
Ik denk ineens wél weer te weten waarom ik dat deed en tegelijkertijd snap ik niet waar mijn hoofd op dat moment zat. De context zag er als volgt ongeveer uit:YellowOnline schreef op woensdag 09 mei 2012 @ 18:53:
Ik heb in een van m'n scripts het volgende:
PowerShell:
1 $zero = 0
Vraag me niet meer waarom, maar ik weet dat het echt een reden had
PowerShell:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| $Zero = 0 $Counter = $Zero While ($Counter -NE $SomeVariable) { #Do something $Counter++ } $Counter = $Zero While ($Counter -NE $SomeOtherVariable) { #Do something $Counter++ } |
't Ontgaat me waarom ik niet gewoon $Counter = 0 doe, maar morgen op het werk kan ik wel eens uitchecken hoe het vork echt in de steel zat.
Klinkt als een typen met gedachten er half bij ietsYellowOnline schreef op woensdag 09 mei 2012 @ 19:23:
[...]
Ik denk ineens wél weer te weten waarom ik dat deed en tegelijkertijd snap ik niet waar mijn hoofd op dat moment zat. De context zag er als volgt ongeveer uit:
PowerShell:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $Zero = 0 $Counter = $Zero While ($Counter -NE $SomeVariable) { #Do something $Counter++ } $Counter = $Zero While ($Counter -NE $SomeOtherVariable) { #Do something $Counter++ }
't Ontgaat me waarom ik niet gewoon $Counter = 0 doe, maar morgen op het werk kan ik wel eens uitchecken hoe het vork echt in de steel zat.
Er klopt iets niet in dat script. Het had moeten zijn:
code:
1
| $Zero = 1 |
We are shaping the future
Dit heeft toch niets met Open Source te maken? Als het closed source geweest was, was de kwaliteit er niet beter op geweest. Sterker nog, omdat het Open Source is, kan jij nu bijdragen door het te verbeterenVerwijderd schreef op woensdag 09 mei 2012 @ 15:52:
Open Source is ook niet heiligVandaag was ik op zoek naar een programma op iWork .pages bestanden te converteren. Toen kwam ik op dit leuke programmatje:
[...]
Eigenlijk is heel Java een slecht programmeervoorbeeld
[hapmodus]
Care to elaborate?
Care to elaborate?
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| //Login process function check_login($input) { include('../inc/settings.php'); $pass_1=md5($adminpassword); $pass_2=md5($input); if($pass_1==$pass_2) { return true; } else { return false; } } |
Even voor de goede orde: settings.php is een file die puur variabelen defineerd zoals $adminpassword.
[ Voor 24% gewijzigd door Zeebonk op 10-05-2012 16:27 ]
Ook nog in plain-text zo te zien. En dan toch gewoon even allebei door de md5 heen halen, want het moet wel secure natuurlijk!Zeebonk schreef op donderdag 10 mei 2012 @ 16:25:
PHP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 //Login process function check_login($input) { include('../inc/settings.php'); $pass_1=md5($adminpassword); $pass_2=md5($input); if($pass_1==$pass_2) { return true; } else { return false; } }
Even voor de goede orde: settings.php is een file die puur variabelen defineerd zoals $adminpassword.
Ik vind de
ook wel mooi eigenlijk
PHP:
1
2
3
4
5
6
7
8
| if($a==$b) { return true; } else { return false; } |
ook wel mooi eigenlijk
Ipsa Scientia Potestas Est
NNID: ShinNoNoir
Ik douw gewoon zelf de eentjes en nulletjes de processor in. Haskell, bah.RayNbow schreef op donderdag 10 mei 2012 @ 18:21:
Iedereen weet toch dat alles behalve Haskell bagger programmeertalen zijn?
I'm not a complete idiot. Some parts are missing.
.Gertjan.: Ik ben een zelfstandige alcoholist, dus ik bepaal zelf wel wanneer ik aan het bier ga!
Met twee pez-dispensers in de hand een beetje tegen je cpu te frotten. Goed plan.Firesphere schreef op donderdag 10 mei 2012 @ 18:27:
[...]
Ik douw gewoon zelf de eentjes en nulletjes de processor in. Haskell, bah.
Verwijderd
Niet iedereen weet dat $a==$b een boolean waarde geeft, o wacht.deadinspace schreef op donderdag 10 mei 2012 @ 17:12:
Ik vind de
PHP:
1 2 3 4 5 6 7 8 if($a==$b) { return true; } else { return false; }
ook wel mooi eigenlijk
Valt mee, maar het is zoveel codeCornholio schreef op donderdag 10 mei 2012 @ 14:57:
Eigenlijk is heel Java een slecht programmeervoorbeeld
De stap van 'iets dat je aan een 'if' kunt voeren naar 'bruikbaar datatype' is voor sommigen gewoon een brug te ver. De meeste mensen groeien daar wel overheen; ik schaam me nog steeds diep voor een aantal dingen die ergens in productie draaien.Verwijderd schreef op donderdag 10 mei 2012 @ 20:48:
Niet iedereen weet dat $a==$b een boolean waarde geeft, o wacht.
Net begonnen met Delphi, en in plaats van
Delphi:
1
| Format('0 padded decimal = <%.6d>', [1234]) |
had ik een hele rij aan functies (en niet alleen voor de 6 ...)
Delphi:
1
2
3
4
5
| function Pad6 (input: String): String; begin case Lenght(input) of 0: Result := '000000'; 1: Result := '00000' + input; |
"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock
Mwah, niet vergelijkbaar imho. De eerste is een onbegrip van het concept van datatypes, expressies en variabelen. Het tweede is het (nog) niet bekend zijn met een specifieke functie en daardoor daar dan een compleet valide eigen implementatie van maken.
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Nou, dat tweede vind ik ook een gebrek aan inzicht. Als je als programmeur functies als Foo1, Foo2, Foo3 gaat schrijven dan moet er toch een lampje gaan branden van "dat kan makkelijker". En als dat lampje brand is een collega of got snel te vinden.
Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info
Verwijderd
Momenteel op http://ldt.nl: een wachtrij
JavaScript:
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
| var intStartPosition = 7; function Update(intPosition) { var intTimeOut; if (intPosition > 0) { // update bar var intPercentage = Math.round((intPosition*100)/intStartPosition); UpdateBar(intPercentage); if (intPosition > 1000) { intTimeOut = 270000; // 4,5min - >1000 wachtenden } else if (intPosition > 500) { intTimeOut = 270000; // 4,5min - 500-1000 wachtenden } else if (intPosition > 250) { intTimeOut = 120000; // 2min - 250-500 wachtenden } else if (intPosition > 100) { intTimeOut = 60000; // 60sec - 100-250 wachtenden } else if (intPosition > 50) { intTimeOut = 30000; // 30sec - 50-100 wachtenden } else if (intPosition > 10) { intTimeOut = 15000; // 15sec - 10-50 wachtenden } else { intTimeOut = 10000; // 10sec - 0-10 wachtenden } // laat msg met waarschuwing zien: window.setTimeout("xajax_GetPositionInQueue(" + intStartPosition + ")", intTimeOut); } else { window.location="http://ldt.nl/"; } } function UpdateBar(intPercentage) { strWidth = (intPercentage) + '%'; nodImg = document.getElementById('imgQueueIndicator'); nodImg.style.width = strWidth; } function StartUpdate() { Update(7) } addLoadEvent(StartUpdate) |
Als je alleen de 6, 10 en 12 nodig hebt en er geen collega voor handen is dan is die oplossing (bedrijfseconomisch) beter dan gaan zoeken wat de betere manier isGrijze Vos schreef op vrijdag 11 mei 2012 @ 09:39:
Nou, dat tweede vind ik ook een gebrek aan inzicht. Als je als programmeur functies als Foo1, Foo2, Foo3 gaat schrijven dan moet er toch een lampje gaan branden van "dat kan makkelijker". En als dat lampje brand is een collega of got snel te vinden.
Het is beiden gewoon bekendheid met het systeem (al grijpt de ene iets dieper in op de concepten en de andere op de implementatie); dat er uit die expressie met integers (of strings) een boolean komt rollen en niet slechts 'iets dat je in een IF kunt stoppen' (ga maar zoeken, verreweg de meeste vergelijkingsoperaties staan in een if of een loop) is een concept dat je door moet hebben, en die bewustwording moet ook groeien.
"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock
Dit topic is gesloten.
![]()
Let op:
Uiteraard is het in dit topic niet de bedoeling dat andere users en/of topics aangehaald worden om ze voor gek te zetten. Lachen om je eigen code, of over dingen die je "wel eens tegengekomen bent" is prima, maar hou het onderling netjes.
Uiteraard is het in dit topic niet de bedoeling dat andere users en/of topics aangehaald worden om ze voor gek te zetten. Lachen om je eigen code, of over dingen die je "wel eens tegengekomen bent" is prima, maar hou het onderling netjes.