2009-12-22 25 views
9

Ich habe einen Checkout-Prozess für einen Einkaufswagen, der derzeit Kreditkartendaten in der Sitzung zum Abruf speichert, sobald der Benutzer den Kauf abgeschlossen hat. Der Kaufvorgang ist so eingerichtet, dass der Benutzer die Kreditkarte eingibt, eine Bestätigungsseite ansieht und dann die Bestellung abschließt. Die Bestätigungs- und Finalisierungsaktionen sind die einzigen beiden Aktionen, die Zugriff auf die Kreditkartendaten benötigen, und um sicher zu sein, sollten alle anderen Aktionen sie verwerfen.ASP.NET MVC - Sichere temporäre Speicherung von Kreditkartendaten

Kurz vor der Reflektion in einem Basis-Controller, um die aktuelle Aktion zu überprüfen, die der Benutzer aufruft, kann ich mir keine elegante Möglichkeit vorstellen, die Daten über die unzulässigen Anfragen zu verwerfen. Wenn der Benutzer nach dem Eingeben der Daten keine weitere Anfrage macht, bleibt er in der Sitzung, bis er auf die Website zurückkehrt - wann immer dies geschieht. Ein Vorschlag, der mir unterbreitet wurde, bestand darin, die Daten in ein verstecktes Feld zu verschlüsseln und sich auf das SSL-Ticket zu verlassen, um das Zwischenspeichern des Markups zu verhindern. Dies scheint ein ziemlich sicherer Ansatz zu sein, aber mir gefällt die Idee nicht, die Kreditkartendaten an einem für den Benutzer zugänglichen Ort verschlüsselt oder nicht zu speichern. Das Speichern in der Datenbank ist nicht möglich, da der Client keine Kreditkartendaten speichern möchte.

Was ist der ideale Ansatz, um vertrauliche Daten wie Kreditkarteninformationen über mehr als eine Seitenanforderung vorübergehend zu erhalten?


Vielleicht kann mir jemand sagen, ob das ein ausreichender Ansatz ist. Ich habe meinen Einkaufswagen festgelegt, der in der Sitzung gespeichert wird, um jedes Mal, wenn das Objekt neu erstellt wird, ein eindeutiges Guid zu generieren, und Guid wird als ein Schlüssel zu dem Verschlüsseln und dem Entschlüsseln der Kreditkartendaten verwandt, die ich mit dem Rijndael algorithm serialisiert. Die verschlüsselten Kartendaten werden dann an den Benutzer in einem versteckten Feld übergeben und deserialisiert, nachdem auf finalisieren geklickt wurde. Das Endergebnis ist eine Zeichenfolge viel wie folgt aus:

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

In Bezug auf Ihr Update: Die Verschlüsselung der Karteninformationen ist nicht die Hürde - es ist schwierig sicherzustellen, dass alle Teile der Lösung sicher sind. Wo speichern Sie beispielsweise die GUID, die als Schlüssel verwendet wird? Hat noch jemand Zugriff auf den Server, der die GUIDs generiert? (Dies kann es jemandem ermöglichen, die GUIDs zu erraten). Verwenden Sie dieselbe GUID pro Sitzung oder pro Anwendungslebensdauer? – meklarian

+0

Auch der Fang {} Block ist ein wenig beängstigend. Wäre es nicht besser, dort einfach eine leere Schnur zurückzugeben? – meklarian

+0

Guter Punkt auf dem ToString() Meklarian. Ich habe das von irgendwo anders kopiert, ohne zu genau hinzusehen. Die GUID wird einmal pro Benutzer pro Sitzung generiert, daher wäre es sehr schwierig, die Guid eines Benutzers zu erhalten, denke ich. –

Antwort

10

Der beste Weg, um dieses Szenario zu behandeln ist, einen Zahlungsdienst zu verwenden, die zwei Dinge unterstützt:

  1. Authorization -> Fertigstellung Semantik.
  2. Tokenisierung

Berechtigung ermöglicht es Ihnen, die bestimmte Ladungsmenge zum Zeitpunkt der Zahlungsinformationen empfangen wird, reservieren und dann Fertigstellung können Sie die Ladung auf die Zahlung Charge verpflichten, sobald die Zahlung/Bestellung bestätigt wird. Wenn der Auftrag storniert wird, müssen Sie keinen Abschluss eingeben und Sie können auch versuchen, die Autorisierung zu löschen.

In Bezug auf die Tokenisierung geben die meisten Gateways, die die oben genannte Zahlungsmethode unterstützen, ein Token zurück, normalerweise eine numerische ID für die ausstehende Transaktion.Das Token kann dann wie gewünscht gehandhabt werden, da es für niemanden ohne Zugriff auf Ihre Authentifizierungsdaten am Gateway einen Wert hat. Dies überträgt die Sicherheitslast auch auf das Gateway.

Das Speichern der eigentlichen Kreditkarteninformationen auf eine andere Weise als das Weiterleiten einer Gebühr an einen Gateway/Prozessor ist eine schlechte Idee. Abgesehen von den Problemen bei der Sicherung der Daten wird Ihre Anwendung auch in den Speicher für Karteninformationsspeicher für PCI/PABP aufgenommen, was viele Regeln und Vorschriften mit sich bringt, die Sie in Ihrer Anwendung nicht behandeln wollen. Ich glaube, es gibt auch eine Regulierungsgebühr, die im kommenden Jahr für konforme Anwendungen, angeblich $ 10k USD, erhoben wird. All dies ist wahrscheinlich nicht die Mühe für Sie oder Ihren Kunden wert.

Zuletzt können Sie während der Zwischenverarbeitung (In-Page/Event/Route-Handler) einen SecureString verwenden, um den Inhalt der Daten zu speichern, bis Sie sie nicht mehr benötigen.

SecureString class (System.Security) @ MSDN

2

Was TempData mit? Sie müssen den Wert zwischen den Bestätigungs- und Finalisierungsaktionen wieder in TempData eingeben, aber er wird zumindest bei jeder Anforderung verworfen. Beachten Sie, dass TempData die Sitzung für den Speicher verwendet, so dass sie nicht mehr sicher ist, während sie gespeichert wird. Sie verfügt jedoch über die Funktion zum automatischen Entfernen. Auch ich würde es ablehnen, die Nummer auf der Seite zu speichern. Ich vermute, dass dies gegen die PCI-Regeln verstößt.

Eine andere Alternative wäre, die Karteninformationen in einer Datenbank zu speichern. Wenn Sie es in Ihrer Anwendung überhaupt behalten, unterliegen Sie wahrscheinlich ohnehin den PCI-Regeln. Das Speichern in der Datenbank erleichtert das, da Sie die Abrechnungskarten-ID nur in nachfolgenden Anfragen eingeben müssen. Dies könnte leicht in einem versteckten Feld sein.

+0

Ich habe gehört, dass TempData nur Daten während Redirects gespeichert hat. Wenn ich es in meinem Controller eingestellt habe, eine Aktion bereitstellen und dann eine Anfrage für eine zweite Aktion verarbeiten, ist TempData an diesem Punkt vorbei, dachte ich? –

+0

TempData wird zwischen zwei beliebigen Anfragen in derselben Sitzung gespeichert. Es wird am besten für Weiterleitungen verwendet, aber es gibt keine technischen Einschränkungen. Das Framework weiß nicht, dass eine eingehende Anfrage das Ergebnis einer Weiterleitung oder einer anderen Aktion ist. – tvanfosson

+0

Wenn das der Fall ist, dann scheint das wie ein sauberer Ansatz. –

0

in welchem ​​Land diese in basiert und welche Kreditkarten-Unternehmen sind beteiligt? Der gesamte Ansatz, tatsächlich die vollständigen Kreditkartennummern an den Kunden zurückzusenden (in welcher Form auch immer), klingt so, als ob Sie nicht mit dem Umgang mit professionellen Kreditkarten behandelt hätten (bitte nehmen Sie das nicht als Beleidigung hin).

Ist Ihr Kunde bereit, gegen die allgemeinen Regeln von Visa/MasterCard/AMC/Discover zur Online-Kreditkartenverarbeitung (PCI DSS) zu verstoßen? Ihr Kunde könnte damit aufhören, von den großen Kreditkartenunternehmen daran gehindert zu werden, Transaktionen mit ihnen zu tätigen. Im Allgemeinen ist es eine sehr schlechte Idee, eine eigene Online-Kreditkartelösung zu rollen - es ist schlimmer, einen eigenen kryptografischen Algorithmus zu erstellen, da es zu erheblichen Bußgeldern für Ihren Kunden kommen kann (Kleingedrucktes in der Händlervereinbarung). Eine echte PCI-DSS-Lösung erfordert Zehntausende von Dollar an Zertifizierungen und Audits, um sicherzustellen, dass sie Kreditkarten-Daten in einer wirklich sicheren Weise verarbeitet - aus diesem Grund verwenden fast alle einen vorhandenen Online-Prozessor.

+0

Nichts für ungerechtfertigt, Sie sind absolut richtig. Der Kunde ist in den Vereinigten Staaten.Offensichtlich wollen wir uns nicht darum kümmern, PCI DSS überhaupt einzuhalten, deshalb ist das Speichern von Daten nicht ideal. –

+0

Die einfachste Möglichkeit, die Speicherung von Kartennummern zu vermeiden, ist die Verwendung einer gehosteten Pay-Page und die Sorge des Providers, die Karteninformationen zu bearbeiten. – tvanfosson

+0

meklarian deckt die Besonderheiten der Verwendung eines vorhandenen Online-Prozessors ab - im Allgemeinen gilt: Je mehr Sie bezahlen, desto mehr können die Prozessoren angepasst werden, so dass ihre Seite nahtlos mit dem Rest Ihrer Website erscheint. – David