I would make a database (this could be an array) that stores every possible code and the code's status (inactive, issued or registered).
When someone bought the software you'd issue a random key code from the remaining inactive ones in the database, they would have to register before using the software. I would have them set up an account with custom user ID and password which would stored on your computer to make sure only they have access to the registered copy.
Another security measure you could add is to store the date the key code was allocated and after a period, if it still hasn't been registered, reset the code's state to inactive. This would prevent "active" codes from stacking up which would have made it easier for fraudsters to guess a valid code. You'd obviously warn the customer prior to doing this and give them a deadline for registration.
I think I had some good ideas there but I've never done any like it before so I don't have a full understanding of what's required.
It is far better to complete a 10 line program than to start a 10,000 line program.
