As you might have noticed, most of the manufacturers use the following architecture/flow for licensing:
1) User gets a generic installer, without any licensee related information within. He/she installs the application.
2) There is a code within and/or in a separate bundled application, that retrieves the system specific information like the ones OriginalGriff has written about (have a look here:
How To Get Hardware Information (CPU ID, MainBoard Info, Hard Disk Serial, System Information , ...)[
^])
3) Now you have several ways to send send this data to you (any or all).
3a) Online - but you say it is offline
3b) Via a web page: you prepare a file with those information (either encrypted or not actually makes no difference, but should have defined a structure, can be an XML for example), the user saves it to a pendrive, and uploads it to your server on an online machine
3c) You make a 10-20 character long machine specific hash from that information, and which can be manually entered on your online site
3d) 3b-3c but you ask the user to send the info to you by email
4) You add some fixed data (salt) to the information you got and generate a hash. This hash is the license code itself.
5) You send this hash back on the channel of your or user's choice
6) In case of 3b-3c you need to ask the user to enter the license code in your application, and you store it in the registry. In case of 3a this can be done automatically.
7) On application start, you gather again all info, add the same salt, generate the hash, and compare. If matches, the license is valid.
8) If there is an expiracy, you should store it separetely in the registry and on your side also, but when generating and validating the hash, you have to add that too.
[Update:]
You can add a higher level of protection using PKI, but won't really be usable as manually enterable code.
9) Generate a publik key-private key pair. Add the public key to teh code, and keep the private code for you.
10) When generating the license code, sign it with your private key, and attach the signature (you can combine in a single structured file)
11) When reading the license code, validate the attached signature first using the public key in your code. If the validation fails, no need to check further.
[Update 2:]
You can not delegate your duty to provide the actual license to the other end of the chain. So if your intention was never to interact in any form with the licensee, than that has no sense. Even if you can protect the file from being tampered, the starting point of your assumtion is wrong: the user can use the original installer to install your application as many different systems as he wants. And that can't be made on-time only, that one can't destroy itself and all it's copies after first installation.