AES is encryption; it is meant to maintain confidentiality. Encryption does not maintain integrity by itself: an attacker who can access encrypted data can modify the bytes, thereby impacting the cleartext data (though the encryption makes the task a bit harder for the attacker, it is not as infeasible as is often assumed).
To get integrity, you need a MAC, and HMAC is a nice MAC algorithm.
In many situations where encryption is mandated, integrity must also be maintained, so, as a general rule, AES "alone" is not sufficient. In your case, the potential attackers are the customers themselves; each customer may try to alter the URL so as to access the data of somebody else, or to be able to register under another name, or whatsnot. As I understand it, your "client" wants to remain the master of registration; he wants to decide which customer can register and under what name. Checked integrity is thus necessary.
There are several ways to combine AES-based encryption with HMAC; most of them are bad. See this question for some discussion on the subject. To make the story short:
If you can, use GCM or some other mode which does all the hard work of combining encryption and MAC safely.
If you cannot use GCM (for lack of support in your server-side programming framework), then you must do things old-style:
- Hash the key K with SHA-256 so as to get 256 bits of "key material". Split that into two halves: 128 bits for encryption (Ke), 128 bits for MAC (Km).
- Generate a random IV of 128 bits. You need a new one every time you encrypt, and you want to generate it with a strong PRNG (
/dev/urandom
).
- Pad the data (usual PKCS#5 padding) so that its length is a multiple of the AES block size (16 bytes).
- Encrypt the data with AES in CBC mode, using the IV generated just above, and Ke as key. Let's call C the resulting ciphertext.
- Compute HMAC/SHA-256 with key Km over the concatenation of IV and C, in that order. Call M the resulting value. It is crucial that the IV is part of the input to HMAC.
- Concatenate IV, C and M, in that order. This is your "registration key".
- When receiving a registration request, first verify the HMAC (by recomputing it), then (and only then) proceed to the decryption step.
Of course, all of this assumes that there is a key K, that your client can use to generate the registration keys for the customers, and that your server also knows in order to verify and decrypt incoming registration requests. As with all keys, be careful where you store it.