E' possibile, ma, come sempre in .NET, non completamente sicuro.
Non c'è bisogno di nessuna logica per generare il seriale. Può essere random come può essere un hash del suo id del database. Se l'attivazione avviene tramite collegamento tra client e database, l'importante non è il codice in sé ma la sua presenza nel database.
Tuttavia non vale lo stesso discorso per le informazioni che devi salvare client-side. Infatti, per sapere se un prodotto è stato registrato ci sono almeno due modi: o ti connetti sempre al server e verifichi la validità del seriale usato (e in questo caso il luogo dove salvi il seriale non ha importanza); oppure crei delle chiavi cifrate che contengano l'informazione riguardante la validità del seriale, ma che siano legate alla macchina o all'utente che le usa, in modo da rendere difficile modificarle arbitrariamente senza corromperle.
Come ho detto all'inizio, però, se scegli di lavorare client-side, non potrai affidarti alla sicurezza del tuo codice, poiché ogni assembly .NET è disassemblabile. Dovrai quindi procurarti un buon offuscatore.