2010-05-01 10 views
5

Ok, sono un po 'bloccato su come risolvere questo problema.ASP MVC: verifica e-mail (crittografia del collegamento di attivazione)

Quando un utente si registra. Voglio mandargli un link in modo che possa verificare l'indirizzo email di hes.

Ma ho problemi a generare il collegamento.

Ho già scritto il controller per accettare i collegamenti con i tasti corretti. non ho idea di come generare le chiavi di attivazione.

Così, quando l'utente si registra Lo manderò un link via e-mail come questa:

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

Ora ho creato questo metodo (chiamato dal controller/azione) per gestire la chiave nel 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!"; 
    } 

Ora il mio problema è che non ho idea su come cifrare e decifrare il messaggio in una sorta di chiave (url amichevole) Così posso spedire con il link e posso usarlo per verificare la posta elettronica.

Ho bisogno di un modo (non complicato ma sicuro) per crittografare l'email in una chiave urlfriendly.

tyvm

risposta

3

Il modo in cui vorrei fare questo è semplicemente generare un largish- random number per la "chiave" e quindi memorizzare una mappatura nel database tra chiave di attivazione e-mail.

5

Potrebbe essere più semplice non utilizzare alcuna crittografia e rendere le cose un po 'più semplici.

Creare un nuovo GUID per il collegamento (e salvare questo con l'utente) poi basta verificare l'utente quando il collegamento viene chiamato

+0

questo è il metodo più semplice, a mio parere –

+1

Se ho capito bene, la versione di Nathan non ha bisogno di salvare per l'utente. Quindi mi sembra più semplice aggiungere 2 funzioni, piuttosto che modificare il DB. –

16

si potrebbe usare qualcosa di simile Rijndael encryption per criptare indirizzo di posta elettronica dell'utente come la verifica chiave, quindi quando fanno clic sul collegamento è sufficiente decrittografare il codice di verifica con la chiave di crittografia privata per recuperare l'indirizzo e-mail e attivare l'utente appropriato. Con questa tecnica non avresti bisogno di memorizzare alcun dato aggiuntivo sull'utente per l'attivazione dell'account e avresti comunque un valore crittografato, molto difficile da indovinare quale codice di verifica.

Ecco un esempio di Rijndael encryption with C#.

Se non si ha familiarità con esso, con la crittografia Rijndael si dispone di una chiave privata che solo tu sai, che viene utilizzata come chiave di crittografia per i tuoi dati. Finché conosci la chiave di crittografia puoi sempre decifrare tutto ciò che hai crittografato.

La bellezza aggiuntiva di questa tecnica è che rende anche facile avere un collegamento in scadenza. Supponiamo ad esempio che desideri un link di reimpostazione della password di 24 ore, quindi invia all'utente un link con un codice di verifica, ma anziché memorizzare i dati sul codice di verifica e la data di scadenza nel tuo sistema, crittografare l'e-mail dell'utente e una data di scadenza e inviarla come codice di verifica. Quindi, in pratica, è possibile crittografare un valore come, 1272746267|14 dove la prima parte è la data/ora di scadenza del collegamento e il secondo valore è l'ID dell'utente nel sistema. Dopo aver decrittografato e analizzato il timestamp, puoi decidere se il link è ancora valido. L'unico inconveniente che vedo in questo approccio è probabilmente la lunghezza della stringa crittografata, ma visto che la stai inviando in una e-mail che non dovrebbe avere importanza.

Ecco un rapido esempio:

Key: a1b2c3d4e5f6h7i8 
Value: 1272746267|14 

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

Assicurarsi di gettare un Url.Encode() sul valore criptato prima di collegarlo, in quanto può contenere alcuni personaggi ostili come barre.

+0

Il valore crittografato di esempio che hai dato contiene caratteri che non sono validi da inserire come parametro nel mio url? sto pensando alle barre ?. –

+0

Ho aggiornato il mio post e ho modificato l'esempio per dimostrare di crittografare un valore meno dettagliato come un timestamp e un ID utente. Per quanto riguarda i caratteri nel valore crittografato, basta chiamare Url.Encode() sul valore prima di includerlo nell'e-mail. –

+0

Buono! Esiste un modo per rilevare se l'e-mail di verifica è stata inoltrata a un altro utente? Devo assicurarmi che colui che fa clic sul collegamento sia il mio utente di destinazione e non un altro utente con un'altra e-mail in modo da impedire agli utenti di condividere le password. –

0

Questo è quello che uso. Breve e facile.

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); 
} 

Risultato simile a questa: 8e85a8a078884bbc

0

cifrare, decifrare utilizzando AES. Trova seguente esempio:

class AesExample 
    { 
     public static void Main() 
     { 
      try 
      { 

       string original = "Here is some data to encrypt!"; 

       // Create a new instance of the AesManaged 
       // class. This generates a new key and initialization 
       // vector (IV). 
       using (AesManaged myAes = new AesManaged()) 
       { 

        // Encrypt the string to an array of bytes. 
        string encrypted = EncryptPasswordAes(original, myAes.Key, myAes.IV); 

        // Decrypt the bytes to a string. 
        string roundtrip = DecryptPasswordAes(encrypted, myAes.Key, myAes.IV); 

        //Display the original data and the decrypted data. 
        Console.WriteLine("Original: {0}", original); 
        Console.WriteLine("Encrypted: {0}", encrypted); 
        Console.WriteLine("Round Trip: {0}", roundtrip); 

        Console.ReadLine(); 
       } 

      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Error: {0}", e.Message); 
      } 
     } 
     static string EncryptPasswordAes(string plainText, byte[] Key, byte[] IV) 
     { 
      // Check arguments. 
      if (plainText == null || plainText.Length <= 0) 
       throw new ArgumentNullException("plainText"); 
      if (Key == null || Key.Length <= 0) 
       throw new ArgumentNullException("Key"); 
      if (IV == null || IV.Length <= 0) 
       throw new ArgumentNullException("Key"); 
      byte[] encrypted; 
      // Create an AesManaged object 
      // with the specified key and IV. 
      using (AesManaged aesAlg = new AesManaged()) 
      { 
       aesAlg.Key = Key; 
       aesAlg.IV = IV; 

       // Create a decrytor to perform the stream transform. 
       ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); 

       // Create the streams used for encryption. 
       using (MemoryStream msEncrypt = new MemoryStream()) 
       { 
        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 
        { 
         using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) 
         { 

          //Write all data to the stream. 
          swEncrypt.Write(plainText); 
         } 
         encrypted = msEncrypt.ToArray(); 
        } 
       } 
      } 


      // Return the encrypted bytes from the memory stream. 
      return Convert.ToBase64String(encrypted); 

     } 

     static string DecryptPasswordAes(string encryptedString, byte[] Key, byte[] IV) 
     { 
      //Convert cipher text back to byte array 
      byte[] cipherText = Convert.FromBase64String(encryptedString); 
      // Byte[] cipherText = System.Text.Encoding.UTF8.GetBytes(encryptedString); 
      // Check arguments. 
      if (cipherText == null || cipherText.Length <= 0) 
       throw new ArgumentNullException("cipherText"); 
      if (Key == null || Key.Length <= 0) 
       throw new ArgumentNullException("Key"); 
      if (IV == null || IV.Length <= 0) 
       throw new ArgumentNullException("Key"); 

      // Declare the string used to hold 
      // the decrypted text. 
      string plaintext = null; 

      // Create an AesManaged object 
      // with the specified key and IV. 
      using (AesManaged aesAlg = new AesManaged()) 
      { 
       aesAlg.Key = Key; 
       aesAlg.IV = IV; 

       // Create a decrytor to perform the stream transform. 
       ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); 

       // Create the streams used for decryption. 
       using (MemoryStream msDecrypt = new MemoryStream(cipherText)) 
       { 
        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 
        { 
         using (StreamReader srDecrypt = new StreamReader(csDecrypt)) 
         { 

          // Read the decrypted bytes from the decrypting stream 
          // and place them in a string. 
          plaintext = srDecrypt.ReadToEnd(); 
         } 
        } 
       } 

      } 

      return plaintext; 

     } 
    } 
Problemi correlati