Tips en Trucs 2016

Pseudo willekeurige wachtwoorden

Veel mensen hebben moeite om hun wachtwoorden te onthouden. Om wachtwoorden veilig op te slaan gebruiken veel gebruikers wachtwoordmanagers. Al uw wachtwoorden worden dan versleuteld met één enkel wachtwoord opgeslagen. Je kunt de opgeslagen wachtwoorden dan enkel lezen als je het versleutelingswachtwoord kent.

Een minder bekende methode bestaat uit het steeds opnieuw genereren van het gebruikte wachtwoord. De procedure bepaalt dan het wachtwoord waardoor de wachtwoorden niet opgeslagen hoeven te worden. De gebruikte procedure om de wachtwoorden te genereren, kan je uitbreiden met een veilig wachtwoord waarmee je de wachtwoordgeneratie personaliseert.

Script

Het onderstaande Bash script is een voorbeeld van zo'n wachtwoordgenerator. Aangezien de gegenereerde wachtwoorden voor een bepaalde dienst steeds hetzelfde moet zijn, mag de generatieprocedure niet willekeurig zijn. Maar we proberen het wel zo willekeurig mogelijk te maken, pseudo willekeurig. Daar het script gebaseerd is op eenvoudige string manipulaties, lussen en voorwaardelijke opdrachten kan het in elke programmeertaal geschreven worden.

De basis

Onderstaande Bash script bevat commentaarregels met uitleg (één #) en uitgeschakelde testregels (met twee #).

#!/bin/bash
# Geef het Hoofdwachtwoord blind -s in
read -p "Hoofdwachtwoord: " -s master
## master="pindanet"
echo
# Geef de diest waarvoor je een achtwoord wilt genereren in
# Mag uit meerder woorden bestaan
read -p "Dienst: " service
## service="Google"
# Geef de lengte van het te genereren wachtwoord in
read -p "Lengte wachtwoord: " pwlen
## pwlen=10
# De tekenreeks char bevat de karakters die in het wachtwoord gebruikt kunnen worden
# Pas de volgorde van deze karakters aan om de pseudo willekeurigheid van het wachtwoord te versterken
# Voeg extra karakters toe om het wachtwoord nog veiliger te maken
char="abcdefghijklmnopqrstuvwxyz0123456789AZERTYUIOPQSDFGHJKLMWXCVBN"
# Maak een wachtwoord met $pwlen karakters
for (( i=0; i<$pwlen; i++ )); do
  # Bereken aan de hand van het hoofdwachtwoord een karakterpositie in de tekenreeks
  masteroffset=`printf '%d' "'${master:$(($i % ${#master})):1}"`
  # Bereken aan de hand van de dienst een karakterpositie in de tekenreeks
  serviceoffset=`printf '%d ' "'${service:$(($i % ${#service})):1}"`
  # Voer bewerkingen uit met de twee karakterposities om een pseudo willekeurige karakterpositie te bekomen
  # De bewerking modulus (rest van deling, %) wordt gebruikt om de karakterpositie binnen de char tekenreeks te houden
  # Varieer de procedure door andere bewerkingen uit te voeren (+ vervangen door met * of %, enz.)
  offset=$(( $((masteroffset + serviceoffset)) % ${#char}))
  # Voeg het karakter op de berekende positie uit de char tekenreeks toe aan het wachtwoord
  password=$password${char:$offset:1}
  ## echo $i $masteroffset $serviceoffset $((masteroffset + serviceoffset)) $offset $char
done
echo Het wachtwoord voor $service is $password
## echo
## echo $master
## echo $service
## echo $pwlen
## echo $char, ${#char}
## echo ${service:1:1}

Bij het uitvoeren van een test met het hoofdwachtwoord pindanet krijg je de volgende uitvoer:

dany@main:~> sh pwgen.sh 
Hoofdwachtwoord: 
Dienst: Google
Lengte wachtwoord: 10
Het wachtwoord voor Google is V49rtzDYZw
dany@main:~> sh pwgen.sh 
Hoofdwachtwoord: 
Dienst: Google
Lengte wachtwoord: 10
Het wachtwoord voor Google is V49rtzDYZw

Vanzelfsprekend gebruik je in de praktijk een veilig hoofdwachtwoord (lang genoeg, zonder woorden, niet te achterhalen, willekeurig, met kleine letters, hoofdletters en cijfers). Dit hoofdwachtwoord is het enige wachtwoord dat je moet onthouden, kennen. Voer de opdracht tweemaal uit om tikfouten uit te sluiten.

Uitbreiden

Door het toevoegen van allerlei tekenreeksbewerkingen kan je pseudo willekeurigheid nog laten toenemen. Zo kan je voor elk karakter in het wachtwoord de char tekenreeks omkeren:

    # Keer de char string telkens om
    rev=""
    for(( ii=0 ; ii<${#char} ; ii++ )); do rev="${char:ii:1}$rev"; done
    char=$rev

Of je verschuift bij elke doorgang de karakters een aantal plaatsen, in het voorbeeld met offset plaatsen:

    # Verschuif de karakters telkens
    char=${char:${#char}-$offset:$offset}${char:0:${#char}-$offset}

Door beide tekenreeksbewerkingen bij elke doorgang uit te voeren, wordt de pseudo willekeurigheid nog groter. Varieer door de volgorde van deze bewerking aan te passen.

Je hoeft de tekenreeksbewerkingen ook niet elke doorgang uit te voeren, zo toon ik in het voorbeeld hieronder hoe bij een even offset de tekenreeks omkeert en bij een oneven offset de karakters in de tekenreeks verschoven worden.

#!/bin/bash
# Geef het Hoofdwachtwoord blind -s in
read -p "Hoofdwachtwoord: " -s master
## master="pindanet"
echo
# Geef de diest waarvoor je een achtwoord wilt genereren in
# Mag uit meerder woorden bestaan
read -p "Dienst: " service
## service="Google"
# Geef de lengte van het te genereren wachtwoord in
read -p "Lengte wachtwoord: " pwlen
## pwlen=10
# De tekenreeks char bevat de karakters die in het wachtwoord gebruikt kunnen worden
# Pas de volgorde van deze karakters aan om de pseudo willekeurigheid van het wachtwoord te versterken
# Voeg extra karakters toe om het wachtwoord nog veiliger te maken
char="abcdefghijklmnopqrstuvwxyz0123456789AZERTYUIOPQSDFGHJKLMWXCVBN"
# Maak een wachtwoord met $pwlen karakters
for (( i=0; i<$pwlen; i++ )); do
  # Bereken aan de hand van het hoofdwachtwoord een karakterpositie in de tekenreeks
  masteroffset=`printf '%d' "'${master:$(($i % ${#master})):1}"`
  # Bereken aan de hand van de dienst een karakterpositie in de tekenreeks
  serviceoffset=`printf '%d ' "'${service:$(($i % ${#service})):1}"`
  # Voer bewerkingen uit met de twee karakterposities om een pseudo willekeurige karakterpositie te bekomen
  # De bewerking modulus (rest van deling, %) wordt gebruikt om de karakterpositie binnen de char tekenreeks te houden
  # Varieer de procedure door andere bewerkingen uit te voeren (+ vervangen door met * of %, enz.)
  offset=$(( $((masteroffset + serviceoffset)) % ${#char}))
  # Voeg het karakter op de berekende positie uit de char tekenreeks toe aan het wachtwoord
  password=$password${char:$offset:1}
  # Bij even offset
  if [ $((offset % 2)) -eq 0 ]; then
    ## echo "$offset is even"
    # Keer de char string telkens om
    rev=""
    for(( ii=0 ; ii<${#char} ; ii++ )); do rev="${char:ii:1}$rev"; done
    char=$rev
  fi
  # Bij oneven offset
  if [ $((offset % 2)) -eq 1 ]; then
    ## echo "$offset is oneven"
    # Verschuif de karakters telkens
    char=${char:${#char}-$offset:$offset}${char:0:${#char}-$offset}
  fi
  ## echo $i $masteroffset $serviceoffset $((masteroffset + serviceoffset)) $offset $char
done
echo Het wachtwoord voor $service is $password
## echo
## echo $master
## echo $service
## echo $pwlen
## echo $char, ${#char}
## echo ${service:1:1}
Pseudo willekeurige wachtwoord generator

Eigen inbreng

Neem dit script niet letterlijk over om uw pseudo willekeurige wachtwoorden voor uw eigen diensten te genereren, maar gebruik uw fantasie om de hier gebruikte technieken te combineren, verder uit te werken en aan te vullen met nieuwe technieken. Hou het script en uw hoofdwachtwoord geheim, hoe minder er uitlekt, hoe veiliger uw wachtwoorden zijn.