Forensisch e-mailonderzoek
Klantcase
Ruim 160.000 e-mails, één controleerbaar feitenoverzicht: forensisch e-mailonderzoek met AI
Twee ondernemers moesten objectief en controleerbaar laten zien welk werk zij over bijna twintig jaar aan een vastgoedproject hadden verricht. De sporen zaten in hun eigen mailboxen: ruim 160.000 berichten en ruim 40 GB aan mailbestanden, deels oud en zelfs beschadigd. Wij bouwden een eigen forensische pipeline in Python die alles uitlas, ontdubbelde en doorzoekbaar maakte, en daarop een feitenoverzicht waarin elke bevinding terug te voeren is op het oorspronkelijke bericht. Op tijd, zodat hun adviseurs er direct mee verder konden.
In het kort
Opdracht: feiten vaststellen uit ruim 160.000 e-mails over bijna twintig jaar
Herken je dit? tienduizenden e-mails, verspreid over jaren en systemen, en één vraag waar je zeker van moet zijn
Bronnen: ruim 40 GB aan mailbestanden: zes Outlook-archieven, waarvan het grootste beschadigd, een Exchange-mailbox, een Gmail-export en een Windows Mail-database uit het Vista-tijdperk
Aanpak: een eigen pipeline in Python die de archieven uitleest, ontdubbelt, in gesprekken ordent en doorzoekbaar maakt, met automatische controles op elke stap
Resultaat: drie samenhangende documenten, op tijd bij de adviseurs, waarin elke bevinding te herleiden is tot de bron
Samenwerking: korte lijnen met de klanten en hun adviseurs, en bij elke nieuwe versie een duidelijke lijst van wat er veranderde
Verantwoord: de bron vastgezet, elke stap controleerbaar en neutraal uitgevoerd, zodat de uitkomst overeind blijft
Omdat het om een vertrouwelijk dossier gaat, beschrijven we deze case zonder namen en zonder inhoud.
De uitdaging: twintig jaar mail, verspreid over oude bestanden
Het werk besloeg bijna twintig jaar. Veel ervan was mondeling of op locatie gegaan, en had weinig sporen nagelaten. Wat er wel was, zat verspreid over technisch heel verschillende bronnen: zes Outlook-archieven (OST-bestanden), een Exchange-mailbox in de cloud, een Gmail-export in mbox-formaat, een Windows Mail-database uit het Vista-tijdperk en losse contactbestanden. Het grootste Outlook-bestand, ruim 8 GB, kwam beschadigd binnen.
Wie in zo’n archief zoekt op een woord als “verkoop”, vindt vooral ruis. En alles moest standhouden onder een kritische blik van buitenaf, met een harde deadline. Eén verzonnen detail, en de geloofwaardigheid van het hele dossier staat op het spel.
Stap 1: de bron vastzetten
Het onderzoek stond onder leiding van Yasar Yigitturk, mede-oprichter van Het AI Lokaal en oprichter van ITR Connect. Voordat we iets analyseerden, zetten we de bron vast, zoals dat hoort in digitaal forensisch onderzoek:
Volledigheid gecontroleerd. Alle aangeleverde bestanden zijn met rclone op checksums vergeleken: nul verschillen.
Een vingerafdruk per bestand. Van elk bestand een SHA-256-hash in een manifest. De originelen staan op alleen-lezen, en de database is alleen in leesmodus geopend.
Aantoonbaar onveranderd. Na elke run zijn de bronbestanden opnieuw vergeleken met het manifest: 23.185 bestanden, allemaal byte voor byte identiek.
Het beschadigde bestand haalden we opnieuw binnen met een kopie die op checksums werd gecontroleerd. Tegelijk exporteerden we de live mailbox via IMAP, als tweede, onafhankelijke bron. Waar de twee overlapten, diende die overlap als onderlinge controle.
Stap 2: een eigen pipeline in Python
Voor dit mengsel van formaten bouwden we een eigen verwerkingspipeline in Python, met een eigen parser per soort bron:
Uitlezen. Outlook-archieven recursief met libpff, inclusief verwijderde items en elk soort item: mail, afspraken, notities, taken en contacten. Mbox-exports gestreamd en veilig gesplitst, en de Windows Mail-database (een ESE-database) met een eigen lezer.
Normaliseren. Datums tijdzonebewust naar UTC, met terugvalregels als een kopdatum ontbreekt of kapot is. Per bericht staat vast waar de datum vandaan komt. Tekensets worden automatisch herkend, en gecodeerde IMAP-mapnamen vertaald.
Niets stil overslaan. Elk bericht wordt apart afgevangen. Een fout stopt nooit de hele run, en wat niet gelezen kon worden, is geteld en gelogd met bron, map en positie.
Ontdubbelen. Eerst op Message-ID. Ontbreekt die, dan op een vingerafdruk van afzender, tijdstip, onderwerp en het begin van de tekst. Elke vindplaats blijft bewaard, met een overlapmatrix tussen de bronnen.
Gesprekken reconstrueren. Via de reply-koppen van elk bericht, met het onderwerp als gemarkeerde terugval.
Doorzoekbaar en reproduceerbaar. Alles in één SQLite-database met full-text search (FTS5), en elk bericht met een vaste bron-ID. Twee runs na elkaar geven exact dezelfde hashes: getest, niet beloofd.
De archieven bleven op eigen hardware: de mail ging voor de analyse niet naar een externe opslagdienst.
Stap 3: zoeken in lagen
Zoeken op trefwoorden levert in zo’n archief vooral ruis op. Daarom zochten we in lagen, van zeker naar minder zeker. Eerst berichten van en aan bekende betrokkenen, zoals de aannemer, de bank, de notaris en de gemeente. Dan de namen van de bedrijven en het project. Daarna documenten in de bijlagen, zoals offertes, bestekken en aktes. En pas daarna inhoudswoorden, alleen binnen wat de eerdere lagen al opleverden.
Het vinden gebeurde niet met machine learning, maar met vaste zoekregels op hele woorden. Dat verschil is groot: een zoekopdracht die ook op stukjes woord matchte, gaf 10.672 treffers waar het er 1.730 hoorden te zijn. Elke telling kreeg daarom een eigen meetsleutel, zodat iedereen hem kan narekenen.
Ontbrak de eigen verzonden post uit de eerste jaren? Dan reconstrueerden we die uit de citaten in antwoorden van anderen. En de agenda’s lieten afspraken zien: juist het werk dat geen mail achterlaat.
Stap 4: bewijzen dat het klopt
In een dossier als dit is output zonder controle waardeloos, of zelfs gevaarlijk. Daarom gold één harde regel: geen bewering zonder bron. Elke bevinding draagt de Message-ID en de datum, en citaten staan er letterlijk zoals in de bron.
Automatische poorten. Voor elke versie liepen controles op citaten, kruisverwijzingen, tabellen en de hashes uit het manifest. Klopt er één niet, dan gaat de versie niet de deur uit. Met mutation testing toetsten we of die poorten echte fouten ook tegenhouden.
AI helpt, de bron beslist. AI hielp bij het lezen, ordenen en controleren, maar elke bewering moest door dezelfde poorten.
Eén bron, drie formaten. De documenten komen uit één markdown-bron en worden gerenderd naar PDF, Word en Excel, met ingebedde lettertypes en een visuele controle van elke pagina.
Corrigeren zonder herbouw. De laatste correctie gebeurde in de PDF zelf, met PyMuPDF. Links en bladwijzers bleven intact, qpdf keurde de structuur, en een tekstvergelijking per pagina toonde aan dat alleen de bedoelde pagina’s veranderden.
Neutraal blijven
Wij leveren de kaart, de adviseurs bepalen de route. Wij leverden feiten met bron en datum; de beoordeling bleef bij de adviseurs van de klanten. Op hun verzoek haalden we in latere versies elke beschouwing eruit, in beide richtingen. Wat overbleef was puur feitelijk: wat, wanneer, wie en waar. Twijfelgevallen legden we voor, in plaats van zelf te beslissen.
Zo werkten we samen
Strakke planning naar een harde deadline. De stukken moesten op een vaste datum bij de adviseurs liggen, en dat lukte.
Korte lijnen. De klanten waren nauw betrokken en gaven in meerdere rondes feedback. Hun wensen verwerkten we snel, ook als het om details ging.
Heldere versies. Elke nieuwe versie zegt op de eerste bladzijde wat er veranderde. De nummering bleef gelijk, zodat de verwijzingen van de adviseurs bleven kloppen.
Binnen de opdracht blijven. Een opschoonronde is geen nieuwe analyse. Zo bleef het werk overzichtelijk, en de kosten ook.
Het resultaat
Een samenhangende set van drie documenten, op tijd bij de adviseurs: een feitenoverzicht per archief en een neutrale leeswijzer die beide verbindt, met de volledige lijst van stukken als bijlage. Alles als PDF en Word, de lijst ook in Excel, met een manifest waarmee de ontvanger zelf kan narekenen dat alles compleet en ongewijzigd is aangekomen.
De techniek in het kort: Python 3.12, libpff, charset-normalizer en python-dateutil voor het uitlezen, SQLite met FTS5 voor het zoeken, SHA-256-manifesten en rclone voor de integriteit, en PyMuPDF, qpdf, poppler, LibreOffice en docx-js voor de documenten.
Over de uitkomst van het dossier zelf zeggen we niets. Dat is aan de klanten.
Yasar en zijn team hebben voor ons een e-mailarchief van tienduizenden berichten over ruim tien jaar doorgelicht, en daaruit een overzichtelijke en controleerbare set rapportages gemaakt. Elke bevinding is terug te voeren op het oorspronkelijke stuk, zodat onze adviseurs er direct mee verder konden. Ze werkten nauwkeurig, dachten kritisch mee en verwerkten onze wensen snel, ook als het om details ging. Een technisch lastig klusje, heel goed afgerond.
Theo Jaspers
Eigenaar,
THJ Advies B.V.
Moet jij grote hoeveelheden mail of documenten doorgronden?
Bij een overname, een audit of een interne vraag: wij ontsluiten je archief objectief en controleerbaar, zodat jouw adviseurs ermee verder kunnen. Neem contact op.
Veelgestelde vragen
Wat is forensisch e-mailonderzoek?
Het systematisch ontsluiten en doorzoeken van e-mailarchieven om feiten vast te stellen: wie schreef wat, wanneer en aan wie. Het wordt ook wel e-discovery genoemd. Het verschil met gewoon zoeken: elke bevinding moet controleerbaar terug te voeren zijn op de bron.
Kun je oude of beschadigde Outlook-bestanden uitlezen?
Ja. Met eigen parsers in Python lezen we Outlook-archieven volledig uit, inclusief verwijderde items, agenda’s en notities. Een beschadigd bestand vangen we op met een tweede, onafhankelijke bron, zoals de live mailbox via IMAP.
Hoe voorkom je dat AI dingen verzint in een gevoelig dossier?
Door AI nooit het laatste woord te geven. Het vinden gebeurt met vaste zoekregels, elke bevinding draagt de Message-ID en de datum, en automatische controles houden elke versie tegen waarin een citaat niet letterlijk in de bron staat.
Hoe bewijs je dat de bron niet is veranderd?
Met een SHA-256-hash per bestand in een manifest, originelen op alleen-lezen en een nieuwe vergelijking na elke run. In deze opdracht bleven alle 23.185 bronbestanden byte voor byte identiek.
Blijven vertrouwelijke mails binnen?
In deze opdracht wel. De archieven bleven op eigen hardware en gingen voor de analyse niet naar een externe opslagdienst.





