views:

256

answers:

4

Okay i'm a little bit stuck on how to solve this problem.

When a user registers. I want to send him a link so that he can verify hes email address.

But i have troubles generating the link.

I've already written the controller to accept the links with the correct keys. i only have no idea on how to generate the activation keys.

So when the user registers i'll send him a link by mail like this:

Your activation link is : http://site.com/user/verify?key=keyhere

Now i have created this method (called by the controller/action) to handle the key in the link:

 public string Verify(string value)
    {
        String email = Decrypt(value);

        user u = gebRep.GetUsers().WithEmail(email).SingleOrDefault();
        if (u != null)
        {
            u.emailValid = true;
            userReppository.Save();
        }

        return "Invallid validation value!";
    }

Now my problem is I have no idea on how to encrypt and decrypt the email into some sort of key (url friendly) So i can mail it with the link and can use it to verify the email.

I need some kind of (not to complicated but secure) way to encrypt the email into a urlfriendly key.

Tyvm

+3  A: 

The way I would do this is simply generate a largish-random number for the "key" and then store a mapping in your database between activation key and email.

Dean Harding
+3  A: 

It may easier to not use any encryption and make things a bit more simple.

Create a new Guid for the link (and save this with the user) then just verify the user when the link is called

Mark Redman
this is the easiest method in my opinion
Alastair Pitts
+2  A: 

You could use something like Rijndael encryption to encrypt the user's e-mail address as the verification key, then when they click the link you simply decrypt the verification code with your private encryption key to retrieve the e-mail address and activate the appropriate user. With this technique you would not need to store any extra data about the user for account activation and you'd still have an encrypted, very hard to guess value as the verification code.

Here's an example of Rijndael encryption with C#.

In case you weren't sure, with Rijndael encryption you have a private key that only you know which is used as the encryption key for your data. So long as you know the key you can always decrypt whatever you encrypt. The additional beauty of this technique is that it also makes it easy to have an expiring link. Say for example you want a 24 hour password reset link, so you send the user a link with a verification code in it, but rather than storing data about the verification code and its expiration date in your system, encrypt the user's e-mail and an expiration date and send that as the verification code. So basically, you could encrypt a value like, 1272746267|14 where first part is the link expiration timestamp and the second value is the user's ID in the system. Upon decrypting and parsing out the timestamp you can make the decision right there whether or not the link is still valid. The user will never know any better. The only drawback I see to this approach is possibly the length of the encrypted string, but seeing as you're sending it in an e-mail that shouldn't matter too much. :)

Key: a1b2c3d4e5f6h7i8
Value: 1272746267|14

Encrypted: wxtVC1u5Q7N9+FymCln3qA==
Decrypted: 1272746267|14

Be sure to throw a Url.Encode() on the encrypted value though as it can contain some unfriendly characters like slashes.

Nathan Taylor
The example encrypted value that you gave contains characters that are not valid to put as a parameter in my url? i'm thinking of the slashes?.
wh0emPah
I've updated my post and modified the example to demonstrate encrypting a less verbose value such as a timestamp and a user ID. As far as the characters in the encrypted value are concerned, just call Url.Encode() on the value before you include it in the e-mail.
Nathan Taylor
A: 

This is what I use. Short and easy.

private string GetNewValidationCode()
{
    long i = 1;
    foreach (byte b in Guid.NewGuid().ToByteArray())
    {
        i *= ((int)b + 1);
    }
    return string.Format("{0:x}", i - DateTime.Now.Ticks);
}

Result looks like this: 8e85a8a078884bbc

rboarman