Hier zal ik een aantal stappen doorlopen om cryptografie in Python te doen.
Stap 1: Symmetrische encryptie:
Hier kun je zien hoe encryptie en decryptie werken op een symmetrische wijze met een sleutel om een boodschap te encrypteren aan de hand van een geëncrypteerd wachtwoord:
De code:
from cryptography.fernet import Fernet
key = Fernet.generate_key()
print(“er wordt een sleutel gegenereerd”)
print(key)
print(“nu gaan we met deze sleutel een boodschap encrypteren. We hebben wel eerst een boodschap nodig.”)
print(“onze boodschap \”my deep dark secret\” wordt eerst omgezet naar bytes, dit verstaat de functie wel. Dit doen we met de functie encode()”)
message = “my deep dark secret”.encode()
print(message)
f = Fernet(key)
encrypted = f.encrypt(message)
print(“de geencrypteerde boodschap:”)
print(encrypted)
decrypted = f.decrypt(encrypted)
print(“de gedecrypteerde boodschap”)
print(decrypted)
Het resultaat:

Stap 2: Asymmetrische encryptie:
Hier wordt gebruik gemaakt van een private en een publieke sleutel, die met een bepaald stuk code worden gekozen. De publieke sleutel dient om te encrypteren en de private sleutel om te decrypteren. Dus als je een boodschap verstuurt encrypteer je die eerst met jouw publieke sleutel, en als je er een krijgt decrypteer je de boodschap met jou private sleutel.
De code:
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization
print(“Hier gaan we met private en publieke sleutels werken, meerbepaald het RSA-systeem”)
print(“Eerst gaan we een private sleutel aanmaken.”)
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
print(“De private sleutel”)
print(pem)
print(“Nu gaan we natuurlijk ook een publieke sleutel aanmaken om de boodschap mee te encrypteren”)
print(“De publieke sleutel”)
public_key = private_key.public_key()
pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print(pem)
print(“Ook hier hebben we weer een boodschap om te encrypteren, hier is dat \”encrypt me!\”. Ook hier gaan we deze boodschap weer voor de functie in bytes omzetten.”)
message = b’encrypt me!’
print(message)
print(“Nu gaan we de boodschap encrypteren”)
encrypted = public_key.encrypt(message, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None))
print(“De boodschap”)
print(encrypted)
print(“Decrypteren moet natuurlijk ook gebeuren, dus laten we dat ook maar doen”)
original_message = private_key.decrypt(encrypted,padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),algorithm=hashes.SHA256(),label=None))
print(“De originele boodschap”)
print(original_message)
Het resultaat:

Stap 3: Hashen van bestanden en van wachtwoorden
Bij hashen is het, in tegenstelling tot de vorige twee, niet de bedoeling dat we de data terug in de originele vorm gaan terug krijgen. Wat hier wel de bedoeling is, is zeer simpel: de data omzetten naar iets onleesbaar voor het menselijk oog en brein, maar zeer makkelijk leesbaar en controleerbaar voor een computer. Hiermee kun je dataverlies tegengaan.
De code:
import hashlib
print(“Hier wordt een file gehashet”)
file = “C:\temp\LegoTableCopy.txt” #Location of the file
print(“file pad: ” + file)
BLOCK_SIZE = 65536 #The size of each read form the file
print(“Het aantal bytes dat tegelijk wordt uitgelezen: “)
print(BLOCK_SIZE)
file_hash = hashlib.sha256() # Construct a hash object using our selected hashing algorithm
print(“Een hash object aanmaken voor de hash in te zetten”)
print(“Open het bestand”)
print(“Zolang de file niet volledig is uitgelezen, moet het programma blijven lezen en de tekst in hashes omzetten”)
with open(file, ‘rb’) as f: #Open the file to read the bytes
print(“Lees het bestand de eerste keer uit, het aantal bytes staat hierboven vermeld”)
fb = f.read(BLOCK_SIZE) #Read from the file. Take the amount of bytes declared above
while len(fb) > 0: #While there is still data being read from the file
file_hash.update(fb) #Update the hash
print(“Update de hash”)
fb = f.read(BLOCK_SIZE) #Read the next block from the file
print(“Lees opnieuw uit de file”)
print(“De hash:”)
print(file_hash.hexdigest()) #Get the string from the hash
Het resultaat:

Bij wachtwoorden is dit iets moeilijker, omdat je een salt en een key moet maken. De salt is een random gegenereerde combinatie van bytes, en de key wordt berekend aan de hand van het wachtwoord, de salt, en nog een paar andere parameters. Uiteindelijk kan je met de key de key gaan vergelijken van het ingegeven wachtwoord, en de gebruiker binnenlaten als het dezelfde is, of buitenhouden als het niet hetzelfde is.
De code:
import hashlib
import os
print(“Maak een salt en een paswoord”)
salt = os.urandom(32) #Remember this
print(“salt: “)
print(salt)
password = ‘password123’
print(“Paswoord: ” + password)
print(“Maak een sleutel”)
key = hashlib.pbkdf2_hmac(‘sha256’, password.encode(‘utf-8’), salt, 100000)
print(“Sleutel: “)
print(key)
print(“Opslag van de sleutel en de salt voor verificatie achteraf”)
storage = salt + key
file = open(‘storage.txt’, ‘wb’)
file.write(storage)
file.close()
print(“Uitlezen van de sleutel en de salt”)
file2 = open(‘storage.txt’, ‘rb’)
storagefile = file2.read()
file2.close()
saltfile = storagefile[:32]
keyfile = storagefile[32:]
passwordToCheck = ‘password246’
print(“Het wachtwoord dat we moeten checken: ” + passwordToCheck)
newKey = hashlib.pbkdf2_hmac(‘sha256’, passwordToCheck.encode(‘utf-8’), saltfile, 100000)
print(“De sleutel van dit wachtwoord: “)
print(newKey)
print(“Controle of de wachtwoorden (dus de sleutels) hetzelfde zijn”)
if newKey == key:
print(‘Paswoord is correct’)
else:
print(‘Paswoord is incorrect’)
Het resultaat:

Stap 4: Digitale handtekening
Bij een digitale handtekening kun je een standaard bericht dat alleen jij gebruikt, een soort van wachtwoord dus, gebruiken om documenten te ondertekenen. Dit gebeurt ook met een encryptie-algoritme genaamd RSA. Hierdoor is er een asymmetrische encryptie, en is deze dus veiliger om te gebruiken, en even makkelijk om te controleren.
De code:
from Crypto.PublicKey import RSA
keyPair = RSA.generate(bits=1024)
print(f”Public key: (n={hex(keyPair.n)}, e={hex(keyPair.e)})”)
print(f”Private key: (n={hex(keyPair.n)}, d={hex(keyPair.d)})”)
msg = b’A message for signing’
from hashlib import sha512
hash = int.from_bytes(sha512(msg).digest(), byteorder=’big’)
signature = pow(hash, keyPair.d, keyPair.n)
print(“Signature: “, hex(signature))
hashFromSignature = pow(signature, keyPair.e, keyPair.n)
print(“Signature valid: “, hash == hashFromSignature)
msg2 = b’A message for signing (tampered)’
hash = int.from_bytes(sha512(msg2).digest(), byteorder=’big’)
hashFromSignature = pow(signature, keyPair.e, keyPair.n)
print(“Signature valid: “, hash == hashFromSignature)
Het resultaat:

Stap 5: Laten zien van een certificaat
Hieronder zal je een voorbeeld zien van een HTTPS certificaat dat in orde is.

Stap 6: Onderscheppen van boodschappen met HTTP
Het is niet zo moeilijk (als je tenminste weet hoe) om boodschappen te onderscheppen vanuit ZAP om te lezen wat de verschillende boodschappen zijn in leesbare taal. Hier zal ik laten zien hoe.
Eerst moet je de website in ZAP zetten, en draaien.
Dan kun je bijvoorbeeld dit zien:


Hier kun je vanboven zien dat de zoekopdracht gewoon te zien is, en je kunt ook gewoon de data zien die moet meegegeven worden.
