2009-12-22 18 views
9

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; 
    } 
} 
+0

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

+0

Inoltre, il blocco catch {} è un po 'spaventoso. Non sarebbe meglio solo restituire una stringa vuota lì? – meklarian

+0

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. –

risposta

10

Il modo migliore per gestire questo scenario è quello di utilizzare un servizio di pagamento che supporta due cose:

  1. Autorizzazione -> la semantica di completamento.
  2. Tokenizzazione

Autorizzazione consente di prenotare la quantità di carica designato al momento le informazioni di pagamento è ricevuto, e quindi il completamento permette di commettere la carica per il lotto pagamento una volta che il pagamento/ordine è confermato. Se l'ordine viene annullato, non è necessario emettere un completamento e si può anche tentare di eliminare anche l'autorizzazione.

Per quanto riguarda la suddivisione in token, la maggior parte dei gateway che supportano il suddetto metodo di gestione dei pagamenti restituirà un gettone, in genere un ID numerico, per la transazione in sospeso.Il token può quindi essere gestito come desideri, in quanto non ha alcun valore per nessuno senza accesso alle credenziali di autenticazione al gateway. Ciò trasferisce anche l'onere della sicurezza al gateway.

Memorizzare le informazioni effettive della carta di credito in qualsiasi modo diverso l'inoltro una carica a un gateway/processore è una cattiva idea. Al di là dei problemi di proteggere i dati, questo sarà anche mettere la vostra applicazione in ambito di memorizzazione dati della carta per PCI/PABP, che comporta un sacco di norme e regolamenti che non si vuole affrontare nell'applicazione. Credo che ci sarà anche una tassa di regolamentazione che verrà imposta nel prossimo anno per le richieste conformi, con una cifra stimata di $ 10k USD. Probabilmente non vale la pena per te o per il tuo cliente.

scorso, durante la lavorazione intermedia (in-page i gestori/evento/percorso), è possibile utilizzare un SecureString per contenere il contenuto dei dati fino a quando non si ha più bisogno di loro.

SecureString class (System.Security) @ MSDN

2

Cosa succede ad usare TempData? Dovresti reinserire il valore in TempData tra le azioni di conferma e di completamento, ma almeno verrà scartato a ogni richiesta. Si noti che TempData utilizza la sessione per l'archiviazione in modo che non sia più sicura mentre viene archiviata, ma ha la funzione di rimozione automatica. Anch'io avrei resistito alla memorizzazione del numero sulla pagina. Sospetto che questo violi le regole PCI.

Un'altra alternativa sarebbe quella di memorizzare le informazioni della carta in un database. Se lo tenga per intero nella tua applicazione, probabilmente sei già soggetto alle regole PCI. Memorizzarlo nel DB rende più semplice il fatto che è sufficiente inserire l'ID della carta di fatturazione nelle richieste successive. Questo potrebbe facilmente essere in un campo nascosto.

+0

Ero a conoscenza del fatto che TempData memorizzava solo i dati durante i reindirizzamenti. Se lo metto nel mio Controllore, servo un'azione, quindi elaboro una richiesta per una seconda azione TempData è passato da quel punto che ho pensato? –

+0

TempData viene memorizzato tra due richieste nella stessa sessione. È meglio utilizzato per i reindirizzamenti, ma non esiste alcuna restrizione tecnica su di esso. Il framework non saprà che una richiesta in arrivo è il risultato di un reindirizzamento o di qualche altra azione. – tvanfosson

+0

Se questo è il caso, allora sembra un approccio pulito. –

0

Che paese è questo e ha sede a quello di credito società di carte sono coinvolte? L'intero approccio di inviare effettivamente i numeri di carta di credito completi al cliente (in qualsiasi forma) rende questo suono come se non avessi affrontato la gestione professionale della carta di credito (per favore non prenderlo come un insulto).

è il client disposto a correre afoul delle regole collettive Visa/MasterCard/AMC/Scopri di linea della carta di credito (PCI DSS)? Il tuo cliente potrebbe finire con l'impedire alle principali compagnie di carte di credito di effettuare transazioni con loro. In generale, si tratta di una pessima idea di provare a rotolare la vostra soluzione gestione on-line con carta di credito - è peggio poi posizionare il proprio algoritmo di crittografia, in quanto vi possono essere gravi multe applicate al vostro cliente (stampa fine nel loro accordo mercantile). Una vera soluzione PCI DSS richiede decine di migliaia di dollari in certificazioni e verifiche per garantire che gestisca i dati delle carte di credito in modo veramente sicuro - questo è il motivo per cui quasi tutti utilizzano un processore online esistente.

+0

Nessun reato, hai assolutamente ragione. Il cliente è negli Stati Uniti.Ovviamente non vogliamo preoccuparci di rispettare lo standard PCI DSS, quindi la memorizzazione dei dati non è l'ideale. –

+0

Il modo più semplice per evitare di memorizzare qualsiasi numero di carta consiste nell'utilizzare una pagina di pagamento ospitata e lasciare che il provider si preoccupi di gestire le informazioni della carta. – tvanfosson

+0

meklarian copre le specifiche dell'utilizzo di un processore online esistente - in generale più si paga, più i processori consentiranno la personalizzazione in modo che la loro pagina risulti trasparente con il resto del sito. – David

Problemi correlati