veilige wachtwoorden
Securityvoor dummies

Even een ‘accountje’ maken doen we bijna dagelijks. Er is geen dienstverlener die zonder kan. De tentakels van de AVG zijn nog niet zo ver doorgedrongen dat ook dat aan banden wordt gelegd. Veilig wachtwoord? het hoort wel, en vinden het ook nodig, maar we doen het gewoon niet. Te veel gedoe, moeilijk te onthouden en dus onhandig. Misschien helpt het echte antwoord op het grote “Waarom dan?” om je gedrag aan te passen. Er zit meer achter dan je op het eerste gezicht zou denken. En bovendien heb je met de onderstaande info heb je ook iets leuks bij te dragen aan je buren op het komende buurtfeestje.

In de begindagen van het internet werkte het maken van een account alsvolgt. Je gaf een gebruikersnaam en wachtwoord drukte op OK en de dienstverlener sloeg allebei netjes, zonder verdere aanpassingen, op in een database. Stel je een database voor als een Excel sheet met een lijst met gebruikersnaam en wachtwoorden van alle accounts die ooit werden aangemaakt.

Allemaal prima zolang de database ontoegankelijk is voor buitenstaanders. Maar, wordt het systeem van de dienstverlener gehackt, dan betekende dat alle gebruikersaccounts met gebruikersnaam en wachtwoord direct beschikbaar zijn voor de aanvaller.

Wat bedacht men toen: we gaan wachtwoorden niet meer in clear tekst opslaan, maar “Hashen”. Een zogenaamd cryptografisch valluik mechanisme (in het engels een trap door genoemd). Je stopt willekeurige data, zoals een wachtwoord, in een stukje wiskundige software, het hashing algoritme, dan komt er aan de andere kant een stukje data dat er heel anders uitziet, een “hash“. Stop je er hetzelfde wachtwoord in, dan komt iets onherkenbaars uit, maar wel altijd hetzelfde, uit. Deze hash kan echter nooit meer worden herleidt naar de invoer. Stoppen we het wachtwoord: "12345678" in de hash-software, dan komt daar het volgende uit: "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f". Je kunt het zelf proberen op deze website.

Alle wiskundigen bevestigen het "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f" is op geen enkele manier terug te herleiden naar 12345678. Welnu, een dienstverlener die zijn zaakjes op orde wil hebben zorgt dus dat zijn database er voortaan zo uit ziet.

Maar hoe kun je dan nog inloggen? Hoe weet de dienstverlener dat “12345678” bij de opgegeven hash hoort? Dat is eigenlijk heel simpel. Voordat de dienstverlener controleert of je wachtwoord klopt stopt hij het door jou opgegeven wachtwoord eerst in de hash-software. Als de uitkomst (hash) overeenkomt met de hash van jou wachtwoord in de database, dan heb je blijkbaar het goede wachtwoord ingevoerd. Het grote voordeel is, dat op deze manier de dienstverlener jouw wachtwoord niet hoeft te weten.

Mocht er een dienstverlener zijn die je ooit vertelt dat ze jouw wachtwoord wel even op kunnen zoeken, dan slaan ze dus blijkbaar jouw wachtwoord zonder hash op. Tegenwoordig is dat een praktijk die, met de komst van de AVG, strafbaar is geworden.

Maar “hashen” is ook niet alles…

Maakt het dan uit of je een moeilijk of makkelijk wachtwoord kiest? Ja, absoluut. In het verleden werden nog wel eens databases gestolen met niet-gehashte wachtwoorden. Men heeft van al die wachtwoorden een soort naslagwerk gemaakt: oneindig veel regels met Hash- en wachtwoordcombinaties. Voer een hash in, en het systeem zoekt het bijbehorende wachtwoord op. Uiteraard heeft men voor het gemak voor elke taal de woordenboeken in dit naslagwerk gestopt. Voor elk woord is een hash gemaakt. Zo’n naslagwerk wordt ook wel een Rainbow table genoemd. Deze zijn deels beschikbaar op internet of anders te vinden op het Dark Web.

Naast oude wachtwoorddatabases en woordenboeken, worden ook hashes berekent voor alle karaktercombinaties die mogelijk zijn. Men is begonnen met “a”, “b” … “aa”, “ab” etc… Het berekenen van die hashes kost tijd. Het berekenen van alle variaties voor lange wachtwoorden kost veel computerkracht en dus tijd. Aangenomen wordt dat er geen rainbow tables beschikbaar zijn voor wachtwoorden van 15 karakters en langer. Maar let wel, daarin worden alle karakters gebruikt die mogelijk zijn, dus ook “@(#&$)…0123…”. Dat betekent dus ook, dat er bestanden bestaan die langere wachtwoorden bevatten, maar minder variatie gebruiken, alleen cijfers en letters bijvoorbeeld. Het kiezen van een wachtwoord met bijzondere tekens is dus daarom heel belangrijk.

Kies je een wachtwoord dat in een rainbow table voorkomt, dan is het eigenlijk net alsof je wachtwoord in leesbare tekst in de database staat.

De gouden wachtwoordregels

  1. Kies geen woordenboekwachtwoord.
  2. Kies geen wachtwoord waarvan je weet dat dit al eerder kan zijn gebruikt door iemand anders.
  3. Kies of een heel lang wachtwoord als je geen bijzondere tekens gebruikt (meer dan 30 tot 45 karakters), Een zin bijvoorbeeld.
  4. Kies een korter wachtwoord (vanaf 15 karakters). Maar dan wel met meer dan alleen cijfers en letters.

…en nog iets

Je hebt het vast vaker gehoord: Kies voor elke dienstverlener een ander wachtwoord. Waarom? De bovenstaande eisen aan een wachtwoord zijn best flink. Je weet waarschijnlijk dat je wachtwoorden niet voldoen aan de bovenstaande eisen. De kans is dus groot, als er een hack plaatsvindt en jouw wachtwoord-hash wordt gestolen, dat de aanvallers met een rainbow table vlot je wachtwoord kan achterhalen. Ze zullen dan direct proberen geautomatiseerd bij andere diensten in te loggen met inloggegevens. Gebruik je hetzelfde wachtwoord overal, dan komen ze ook overal zonder problemen binnen met alle bijkomende gevolgen. Het wordt al anders als je aan de gouden wachtwoordregels voldoet. Maar dan nog is het een best practice overal een ander wachtwoord te gebruiken.

Hoe dan?

De moed zakt je misschien in de schoenen als je bedenkt dat je zulke lange moeilijke wachtwoorden moet gaan verzinnen en onthouden. Daarom kun je er voor kiezen om een wachtwoordmanager te installeren of een online dienst af te nemen die dat regelt. Je komt dan met 1 wachtwoord, bij al je andere wachtwoorden. Deze programma’s zijn in staat om moeilijke wachtwoorden voor je te maken en veilig te bewaren en bovendien vaak geautomatiseerd in te loggen. Een programma wat ik zelf altijd gebruik is KeePass Password Safe

Je emailaccount

Een ketting is zo sterk als de zwakste schakel. Je mailaccount is meestal de spin in het web van je veiligheid. Wachtwoord vergeten? Dan laat je je een password reset linkje mailen. Heeft een hacker toegang tot je mail account, dan kun je nog zulke veilige wachtwoorden kiezen voor al je diensten, meestal kan hij dan bijna overal bij. Zorg dus dat je e-mailaccount beter beveiligd is dan de rest. Het is geen overbodige luxe, een tweede factor toe te voegen. Hieronder meer daarover.

De tweede factor

In de security-wereld is beschreven dat je dingen kunt beveiligen met 3 factoren:

  • Iets wat je weet (bijv. een wachtwoord)
  • Iets wat je hebt (bijv. een Identifier van je bank) of
  • Iets wat je bent (bijv. vingerafdruk).

Om de beveiliging op te schroeven kun je, bij sommige dienstverleners, niet slechts 1, maar 2 factoren gebruiken voordat je toegang krijgt. Als je inlogt bij je bank heb je dat vaak al. Je hebt bijvoorbeeld een PIN (iets wat je weet) en een identifier (iets wat je hebt). Zonder die 2 kom je niet binnen. De aanvaller heeft allebei nodig en dat maakt een aanval een stuk moeilijker.

Een tweede factor instellen kan bij veel grote dienstverleners zonder veel moeite. Denk aan Microsoft, Google (gmail) of Amazon. De meestgebruikte tweede factor is een Authenticator App die je installeert op je mobiel. Deze genereert een 6 cijferige nummer dat je na het invoeren van je wachtwoord invoert bij de dienstverlener. Als allebei kloppen, dan ben je binnen.

Ben ik gehackt?

Of de sites van grote dienstverleners zijn gehackt en eventueel wanneer en wat er is gebeurd kun je terugvinden op de site van Have I Been Pwned:. Je kunt daar ook je gebruikersnaam / e-mail invoeren om te controleren of jouw account is gestolen via een gehackte dienstverlener.

Wat te doen als ik ben gehackt?

Als een dienstverlener gehackt blijkt te zijn en jij hebt daar een wachtwoord gebruikt dat je ook bij andere dienstverleners gebruikt? Zorg dan dat je een nieuw en uniek wachtwoord kiest voor elk van deze dienstverleners. Vergewis je ervan dat de betreffende accounts niet ook al zijn misbruikt. Als dat het geval is meld dit dan bij de dienstverlener.

Tot slot

Je kent nu het “waarom” van een veilig wachtwoord. Als je voor veilig gaat, help je daar jezelf mee, maar ook anderen. Want als bijvoorbeeld jouw e-mailadres niet wordt gehackt, kan er ook geen malware via jouw account naar anderen worden verspreidt. Een veilig internet begint dus bij jezelf.

Mocht je nog vragen hebben? Dan hoor ik dat graag. Er zijn geen domme vragen, dus kom maar op 😉

.NETC#Regex

Zoals je in het vorig deel hebt kunnen lezen is de regular expression tester te gebruiken om je regex kennis te praktiseren en expressies uit te testen.

Speciale karakters

Begin van een woord matchen

Het speciale karakter “\b” match een begin van een woord. Hebben we te doorzoeken tekst “Jan loopt met an in het bos met zijn os.” dan vinden we met de volgende reguliere expressie alleen een match op het woord “os”:

\\bos

Een match op de naam “an” maar niet op “Jan” (in dit voorbeeld zonder hoofdletters) verkrijgen we door:

\\ban

Om op elk woord een match te krijgen kan de volgende expressie worden gebruikt:

\\b\\w+

Match op alle karakters

De “.” staat voor een match van alle karakters behalve row breaks en new line karakters:

.+

Bovenstaande matcht de volledige tekst. Overigens heeft de punt (“.”) binnen een karakterklasse (“[.]”) geen speciale betekenis.

Carriage return, Line Feed en Tab

Carriage return en Line Feed worden binnen regex hetzelfde aangeduidt als binnen .NET strings.
De carriage return:

\\r

De line feed:

\\n

De tab:

\\t

Bij het matchen van meerder regels binnen een tekst zijn de karakters van groot belang.

Alternatieven (Alternation)

Binnen karakterklassen wordt er gematcht op karakters binnen de klasse. Dit werkt altijd als een OF. Buiten de klassen wordt standaard als EN gematcht. Een OF match maken op “maandag” of “dinsdag” of “woensdag” gaat via de volgende reguliere expressie:

(maandag|dinsdag|woensdag)

De haken groeperen de opdracht. De pipes (“|”) zorgen voor de OF instructies.

Case (in)sensitive

(?i)

Bovenstaande reguliere expressie maakt alles wat volgt case insensitive. De regulier expressie “(?i)jan” op de te doorzoeken tekst “Jan loopt in het bos” resulteert in een match op “Jan”.

(?-i)

Bovenstaande expressie heft case insensivity weer op.

Gretig of lui repeteren

Stel we hebben de tekst “Jan loopt in het bos. Hij speelt op zijn contrabas.” Als we elke zin willen matchen kunnen we de volgende reguliere expressie maken:

[a-zA-Z\\s]+

Dit zal resulteren in 2 resultaten (gebruik tab 2 in de test tool). Dit is een voorbeeld van greedy repetition. Het matchende resultaat wordt zo lang als mogelijk.
Voegen we echter een “?” aan het speciale repetitiekarakter (“+”) dan schakelen we over naar lazy repetition:

[a-zA-Z\\s]+?

Dit resulteert in 49 resultaten, voor elke letter en spatie 1 resultaat. Zodra er een match is is het afgelopen.

Vooruit en achteruit kijken

Het is mogelijk een match te maken op onderdelen in de tekst zonder ze mee te nemen in het resultaat. We hebben de tekst “Jan loopt in het bos.”. We willen een match op alles wat komt na de tekst “Jan”.

(?<=Jan).*

.* staat voor alle karakters. ?<=Jan is een lookbehind naar de tekst “Jan” zonder deze mee te nemen in het resultaat.
Willen we een match op alles wat komt voor de tekst “bos” dan gebruiken we de volgende regex:

.*(?=bos)

Een combinatie van beide is:

(?<=Jan).*(?=bos)

Alles tussen “Jan” en “bos” wordt gematcht.

Groeperen, verschillende resultaten in een keer matchen

In de tekst: “12 december 2010 19:34:44.999” zouden we bijvoorbeeld de dag en maand + het uur en de minuten kunnen halen. Groepen met namen zijn hier de oplossing. Zo kunnen in een keer op verschillende onderdelen van de tekst matches accuraat worden opgehaald. Dit is vooral handig bij het gebruik in .NET code. Een voorbeeld volgt iets verderop in dit artikel.

(?[1-9][0-9]{0,1}\\s[a-zA-Z]+)\\s[1-9][0-9]{3}\\s(?[1-9][0-9]{0,1}:[0-9]{2}):[0-9]{2}[.][0-9]{3}

De syntax ? binnen de ronde haken zorgt voor naamgeving van een groep. In .NET bevat elke match een groepcollectie waarin de namen en resultaten zijn terug te vinden.

Gebruik van reguliere expressies in .NET

Zoals in de eerste deel van de regex artikelen aangegeven bevindt de regex functionaliteit zich binnen .NET in de System.Text.RegularExpressions namespace. De methode die vooral worden gebruikt voor het valideren en zoeken in de class Regex zijn:

  • IsMatch(string Text, string RegexPattern) resultaat Boolean
  • Matches(string Text, string RegexPattern) resultaat MatchCollection object

Belangrijk is om NIET te vergeten de patterns te escapen:

^\\sbos.$

Wordt in code:

Regex.IsMatch("Jan loopt in het bos.", "\\\\sbos.$");

Bij het gebruik van de Matches functie wordt een MatchCollection object geretourneerd. Dit is een collectie met alle gevonden matches (Match objecten). De gevonden frase kan worden terug in de value property van het Match object.

MatchCollection AllMatches = Regex.Matches("Jan loopt in het bos.", "n"); 
foreach (Match m in AllMatches) 
{ 
  string Frase = m.Value; 
}

Zoals eerder genoemd kan het gebruik van groepsnamen heel handig zijn. In het derde tabblad van de regular expression tester kun je testen met groepen. Voorbeeld:

string text = "12 december 2010 19:34:44.999"; 
string regexPattern = "(?[1-9][0-9]{0,1}\\\\s[a-zA-Z]+)\\\\s[1-9][0-9]{3}\\\\s(?[1-9][0-9]{0,1}:[0-9]{2}):[0-9]{2}[.][0-9]{3}" 
MatchCollection Matches = Regex.Match(text, regexPattern); //er is 1 match 
int GroupCount = Matches[0].Groups.Count; //3 groepen, nl: 1. de gehele match, 2. Groep: DATUM en 3. Groep: TIJD) 
string Datum = Matches[0].Groups["DATUM"].Value; //of Matches[0].Groups[1].Value 
string Tijd = Matches[0].Groups["TIJD"].Value;

Conclusie

Er is nog veel meer te vertellen over regular expressions. Ik hoop dat dit helpt om een eind op weg te komen met regular expressions. Echt de puntjes op de spreekwoordelijke “i” ?. Het boek: Mastering Regular Expressions van O’Reilly vond ik heel leerzaam, het behandeld ook de toepassing van reguliere expressies in .NET.

Vragen of opmerkingen? Aarzel niet, elke reactie is van harte welkom!

.NETC#Regex

Om direct met de regels aan de slag te kunnen die we hieronder gaan bespreken is het handig de snoei.net Regex Tester te gebruiken. Denk nu vooral niet dat dit een hele spannende applicatie is. Het stelt weinig voor, net zoals het gebruik van reguliere expressies binnen het .NET framework.

Door veel softwareontwikkelaars worden regular expressions gebruikt voor de validatie van velden zoals e-mailadres, url, postcode etc… Voor het zoeken van gegevens in grote stukken tekst wordt regex over het algemeen minder gebruikt. De manier waarop regex wordt gebruikt verschilt in beide gevallen niet veel van elkaar. Op beide zijn dezelfde regels van toepassing. We beginnen met de uitleg voor het doorzoeken van tekst. Het valideren van gegevens is dan appeltje/eitje.

In de voorbeelden hieronder worden dubbele quotes (“) gebruikt om een bepaalde tekst, frase of regex aan te duiden. Neem deze dus niet mee in de tests.

Hieronder overzichtelijk een aantal voorbeelden met een stuk tekst en een regular expression om bepaalde gegevens uit de tekst te halen.

Voorbeelden

‘Gewone’ karakters (literals) gebruiken

Tekst: “Jan loopt in het bos”
Zoekopdracht: Komt het woord: “loopt” voor?
Regex:

"loopt"

Uitleg: Voer dit bovenstaande voorbeeld in in op het eerste tabblad van de regular expression tester. Resultaat: een match. Het woord “loopt” komt tenminste 1 keer voor.

Het gebruik van ^ en $

Tekst: “Jan loopt in het bos.”
Zoekopdracht: Bevat de zin exact “Jan loopt in het bos.”?
Regex:

"^Jan loopt in het bos.$"

Uitleg: Het dakje (“^”) duidt aan dat de daaropvolgende tekst aan het begin van de te doorzoeken tekst moet staan. De reguliere expressie “^Jan” levert bijvoorbeeld een match op bij alle teksten die beginnen met “Jan”. Het dollar-teken (“$”) duidt het einde van de tekst aan. De regex “bos.$” levert een match op bij alle teksten die eindigen met “bos.”. Deze 2 in combinatie gebruiken betekent dat alles tussen deze 2-tekens exact overeen moet komen met de te doorzoeken tekst. Herkenbaar? Ja, deze worden bijna altijd samen gebruikt bij validaties.

Omzeilen van speciale karakters
^ en $ zijn dus speciale karakters en geen literals. Als met speciale tekens toch als literals wil gebruiken. Stel je wil een match maken op een dollar teken. Plaats dan een “\” voor het speciale teken. Dus tekst: “$500,-“, regex: “\$500,-” geeft een match.

Wat is een karakter klassen (character classes)

Tekst: “Jan loopt in het bos. Hij speelt op zijn contrabas.”
Zoekopdracht: De termen “bos” en “bas”.
Regex:

"b[oa]s"

Uitleg: Gebruik voor deze test het tweede tabblad van de Regular Expression tester.

Er zijn 2 resultaten, “bos” en “bas”. We maken gebruiken van de zogenaamde character classes. Character classes zijn verzamelingen van karakters die worden omsloten met rechte haken (“[” en “]”). Een karakter klasse definieert welke karakters mogen voorkomen op een bepaalde positie binnen de tekst. In dit geval mag “o” OF “a” voorkomen op een plek tussen “b” en “s”. Het wordt “boos”, “boas” of “baas” zal dus niet in de zoekresultaten voorkomen omdat het hier slechts om 1 positie gaat.

Karakter klassen en karakterreeksen (a-z A-Z)

Tekst: “Jan loopt in het bos. Hij speelt op zijn contrabas.”
Zoekopdracht: Alle termen die beginnen met een “b” en eindigen op een “s” met daartussen 1 ander willekeurig karakter.
Regex:

"b[a-zA-Z]s"

Uitleg: a-z duiden alle kleine letters in het alfabet aan. A-Z alle hoofdletters. “b[a-z]s” zou dus alleen resulteren in een match als er een kleine letter tussen de “b” en de “s” staan. Alle reeksen op een rij:

a-z Kleine letters van “a” tot “z”. Mogelijke variatie: “a-f” = alle kleine letters van “a” tot en met “f”.
A-Z Hoofdletters van “A” tot en met “Z”.
0-9 Alle cijfers van “0” tot en met “9”.
\d Cijfers.
\w Alle woord karakters (alle alfanumerieke karakters inclusief underscore “_”).

Uitsluiten van karakters in een klasse

Tekst: “Jan loopt in het bos. Hij speelt op zijn contrabas.”
Zoekopdracht: Alle termen die beginnen met een “b” en eindigen op een “s” met daartussen 1 ander willekeurig karakter behalve de “a”.
Regex:

"b[^a]s"

Uitleg: Het dakje (“^”) binnen een karakterklasse heeft een geheel andere betekenis als daarbuiten (begin van de te doorzoeken tekst). Met het dakje binnen een karakterklasse wordt een uitsluiting aangeduidt. Er is 1 resultaat: “bos”.

Karakter klasse en herhaling

Tekst: “Jan loopt in het bos. Hij speelt op zijn contrabas.”
Zoekopdracht: Alle termen die beginnen met een “l” en eindigen op een “pt” met daartussen een willekeurig aantal karakters.
Regex;

"l[o]+pt"

Uitleg: Direct achter een karakter klasse kan een herhaling worden aangeduid. “+” staat voor 1 of meer. In dit geval matcht “loopt” omdat tussen “l” en “pt” 1 of meerdere o’s voorkomen. Maar “loooopt” kan ook.

+ 1 of meer
* 0 of meer
{x} (vb. {3}) x aantal keer zoals aangeduid. (vb. 3 keer)
{x,y} (vb. {1,3}) x tot y keer. (vb. 1 tot 3 keer)
\w Alle woord karakters (alle alfanumerieke karakters inclusief underscore “_”).

Conclusie

Een hoop informatie. Met deze informatie zou je al behoorlijk uit de voeten moeten kunnen met regulier expressies. In het 3de een laatste deel de puntjes op de i met betrekking tot reguliere expressies.

In deel 3:

  • Alternation
  • Ankers (Anchors)
  • Special Characters
  • Reguliere expressies in .NET
  • Groeperen

Heb je vragen? Stuur een reactie.

.NETC#Regex

Regular Expressions, Wikipedia zegt er het volgende over:

Een reguliere expressie (afgekort tot “regexp”, “regex” of RE) is een manier om patronen te beschrijven waarmee een computer tekst kan herkennen. Er bestaat hiervoor een formele syntaxis, die grotendeels gestandaardiseerd is.

Kortom regular expressions zijn een krachtige manier om teksten te doorzoeken. Iets om niet zomaar naast je neer te leggen. Een krachtiger taal om tekst te doorzoeken is er bijna niet. Regex worden veel gebruikt voor de validatie van datainvoer zoals het verifiëren van e-mail invoer, numerieke invoer, datums (data ;-)) etc…

Wat ik persoonlijk de moeilijkheid aan regex vond is het onthouden van de regels die erbij horen. Regex is typisch iets wat je in vlagen gebruikt. Zit er een wat langere tijd tussen het toepassen ervan dan zakt alle kennis weer weg. In eerste instantie lijken regular expressions behoorlijk ingewikkeld. Dat dat best meevalt zul je kunnen lezen in de rest van de serie.

Het mooie is dat regex ook in Microsoft .NET goed wordt ondersteund. De regex functionaliteit is terug te vinden in de namespace System.Text.RegularExpressions.

Een goed startpunt is de .NET regular expressions testapplicatie. In deel 2 aandacht voor het het onder de knie krijgen van de regels met behulp van de Snoei.net Regex Tester. Deze Silverlight testapplicatie is een handig hulpmiddel voor mensen die minder van lezen houden en meer van ‘hands-on’ oplossingen.

C# codevoorbeeld:

using System.Text.RegularExpressions; 

public void Test() { 
   string Value = "12345"; 
   string RegexPattern = "^[0-9]{5}$" 
   bool Match = Regex.IsMatch(Value, RegexPattern); //Match = true; 
}