Also, ich hab mir die Sache mal ein bisschen kryptografisch angeschaut.
Etwas stutzig macht mich dabei sofort, dass du in der GUI irgendwo MD5 erwähnst, du aber nirgendwo MD5 verwendest..? Egal.
Was du ja prinzipiell machst, ist einen Hashwert aus den Systemeigenschaften generieren und den abspeichern. Kopiert jemand die Dateien auf einen anderen Rechner, oder bastelt an der EXE rum, dann fällt das natürlich dann auf, das ist ja die Idee hinter dem Schutz.
Die "Verschlüsselung" die du machst, ist nichts weiter als ein XOR aus den Daten der EXE und dem Hash. Du schüttest da noch ein paar Zufallszahlen in die anticop.y rein, aber das ist ja nur Datenmüll zur Verschleierung.
Das heisst, wir haben hier eine synchrone XOR-Verschlüsselung mit ein bisschen Obfuscation. Mit Blowfish hat das herzlich wenig zu tun 
Synchrone "Verschlüsselung" heisst: Jeder kann die Datei entschlüsseln (im Zweifelsfall .NET dekompilieren und den Code anschauen), den Hash rauslesen und einen eigenen Hash reinschreiben (den Hash-Generator getHash() lieferst du ja auch mit, da kommt man auch an den Code ran).
Als potentieller Cracker muss ich also nur ein winziges Programm schreiben, was die anticop.y für den Rechner neu schreibt und fertig.
Von daher schützt dein Code zwar vor einfachem Copy-Paste, aber der Schutz lässt sich problemlos aushebeln, weil du synchrone Verschlüsselung verwendest.
Ein richtiger Kopierschutz müsste mit asynchroner Verschlüsselung arbeiten, wo das Setup oder dein Download-Server den rechnerspezifischen Hash verschlüsselt, wo du beim Überprüfen nur noch entschlüsseln musst und ein Angreifer keine Verschlüsselung basteln kann, weil du den Code zum verschlüsseln nicht mitlieferst.
Solange du aber die Verschlüsselungsroutine inkl. Key im Programm behälst, kann jeder deinen Kopierschutz aushebeln.