Ho un processo di verifica per un carrello acquisti che attualmente memorizza i dati della carta di credito nella sessione per il recupero una volta che l'utente ha finalizzato l'acquisto. Il processo di acquisto è impostato in modo tale che l'utente inserisca la carta di credito, visualizzi una pagina di conferma e quindi finalizzi l'ordine. Le azioni di conferma e finalizzazione sono le uniche due azioni che richiedono l'accesso ai dati della carta di credito e per essere sicuri tutte le altre azioni dovrebbero scartarla.ASP.NET MVC - Archiviazione temporanea sicura dei dati della carta di credito
A corto di fare la riflessione in un controller di base per verificare l'azione corrente che l'utente sta chiamando, non riesco a pensare ad un modo elegante per scartare i dati sulle richieste non consentite. Inoltre, se l'utente non riesce a fare un'altra richiesta dopo aver inserito i dati, si fermerà nella sessione fino a quando non tornerà sul sito web, ogni volta che ciò accade. Un suggerimento che mi è stato offerto è stato quello di crittografare i dati in un campo nascosto e fare affidamento sul ticket SSL per evitare di memorizzare nella cache il markup. Questo mi sembra un approccio abbastanza sicuro, ma non mi piace molto l'idea di mettere i dati della carta di credito in una posizione accessibile all'utente crittografata o meno. L'archiviazione nel database non è disponibile perché il cliente non desidera che i dati della carta di credito vengano salvati.
Qual è l'approccio ideale per la temporanea persistenza di dati sensibili come le informazioni sulla carta di credito su più di una richiesta di pagina?
Forse qualcuno può dirmi se questo è un approccio sufficiente. Ho impostato il mio carrello acquisti che è archiviato nella sessione per avere un GUico univoco generato ogni volta che l'oggetto viene aggiornato e che Guid viene utilizzato come chiave per crittografare e decrittografare i dati della carta di credito che sto serializzando con lo Rijndael algorithm. I dati della carta criptata vengono quindi passati all'utente in un campo nascosto e deserializzati dopo aver fatto clic su finalize. Il risultato finale è una stringa molto simile a questo:
VREZ%2bWRPsfxhNuOMVUBnWpE%2f0AaX4hPgppO4hHpCvvwt%2fMQu0hxqA%2fCJO%2faOEi%2bX3n9%2fP923mVestb7r8%2bjkSVZDVccd2AJzCr6ak7bbZg8%3d
public static string EncryptQueryString(object queryString, Guid encryptionKey)
{
try
{
byte[] key = Encoding.UTF8.GetBytes(ShortGuid.Encode(encryptionKey).Truncate(16));//must be 16 chars
var rijndael = new RijndaelManaged
{
BlockSize = 128,
IV = key,
KeySize = 128,
Key = key
};
ICryptoTransform transform = rijndael.CreateEncryptor();
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Write))
{
byte[] buffer = Encoding.UTF8.GetBytes(queryString.ToString());
cs.Write(buffer, 0, buffer.Length);
cs.FlushFinalBlock();
cs.Close();
}
ms.Close();
return HttpUtility.UrlEncode(Convert.ToBase64String(ms.ToArray()));
}
}
catch
{
return null;
}
}
Per quanto riguarda l'aggiornamento: Crittografia le informazioni della carta non è il hurdle- garantire che tutti i pezzi della soluzione sono sicuro è difficile. Ad esempio, dove stai memorizzando il GUID utilizzato come chiave? Qualcun altro ha accesso al server che genera i GUID? (ciò potrebbe rendere possibile l'individuazione dei GUID da parte di qualcuno). Stai utilizzando lo stesso GUID per sessione o per durata della domanda? – meklarian
Inoltre, il blocco catch {} è un po 'spaventoso. Non sarebbe meglio solo restituire una stringa vuota lì? – meklarian
Buon punto sul meklarian di ToString(). L'ho copiato da qualche altra parte senza guardare troppo da vicino. Il Guid è generato una volta per utente per sessione, quindi ottenere Guid di un utente sarebbe piuttosto complicato, credo. –