2010-07-22 6 views
5

Ich habe mit der System.Security.SecureString-Klasse untersucht, um Kreditkartennummern im Speicher zu halten, während sie verarbeitet werden. Hat jemand die SecureString-Klasse verwendet, um Kreditkartennummern zu halten, oder nutzt er die normale System.String-Klasse?Verwenden Sie SecureString für Kreditkartennummern

+1

Bessere Frage: Ist System.SecureString wirklich sicher genug für diese Anwendung? –

+0

@JSBangs: Nun, nach meinem Verständnis ist System.SecureString speziell für diesen Zweck gedacht. Da jedoch viele andere APIs im .NET-Framework immer noch die normale System.String-Klasse verwenden, ist es schwierig, die Sicherheit der Zeichenfolge in der gesamten Anwendung aufrechtzuerhalten. Ich denke, meine Frage ist wirklich: Lohnt es sich zu versuchen, die Daten von End-to-End im Speicher zu sichern, oder gibt es einfach zu viele Lücken in der API, wo dies nicht unterstützt wird, dass wahre Sicherheit sowieso nicht erreicht würde ? – NYSystemsAnalyst

Antwort

9

Aus PCI-DSS Sicht gibt es keine Anforderung Kartennummern nur im Speicher abgelegt zu schützen.

PCI besagt nur, dass Kartennummern auf der Festplatte gespeichert oder über ein Netzwerk übertragen werden müssen. Dies ist ein vernünftiger Ansatz für das Problem. Mit SecureString wird sichergestellt, dass die Zeichenfolge nie auf der Festplatte zwischengespeichert wird, aber wie Sie sagen - es ist schwierig zu verwenden. Dieser Beitrag hat einige gute Vorschläge: https://stackoverflow.com/questions/122784/hidden-net-base-class-library-classes#123141

In der Theorie klingt der Schutz Speicher wie es Stärke hinzufügen würde, aber in Wahrheit, wenn ein böser Kerl Zugang zum RAM hat, dann ist es ziemlich viel Spiel sowieso.

+0

Die PCI-Anforderungen sind der richtige Ort, um hier eine Antwort zu finden ^^ – cRichter

1

Ich benutze SecureString für andere Dinge (keine Kreditkarten), wenn es für längere Zeit im Speicher zwischengespeichert wird.

Das Problem, auf das ich stoße, ist, dass man es immer noch zu einem normalen String marshallen muss, um es tatsächlich für irgendetwas zu verwenden, so dass es in seiner Nützlichkeit sehr begrenzt ist.

ich ein paar Erweiterungsmethoden erstellt haben, mit ihnen ein wenig zu erleichtern, arbeiten:

public static unsafe SecureString Secure(this string source) 
    { 
     if (source == null) 
      return null; 
     if (source.Length == 0) 
      return new SecureString(); 

     fixed (char* pChars = source.ToCharArray()) 
     { 
      SecureString secured = new SecureString(pChars, source.Length); 
      return secured; 
     } 
    } 


    public static string Unsecure(this SecureString source) 
    { 
     if (source == null) 
      return null; 

     IntPtr bstr = Marshal.SecureStringToBSTR(source); 
     try 
     { 
      return Marshal.PtrToStringUni(bstr); 
     } 
     finally 
     { 
      Marshal.ZeroFreeBSTR(bstr); 
     } 
    } 
+3

Das vereitelt den Zweck. Sobald Sie von/in System.String konvertieren, ist es nicht mehr sicher. –

+0

@Hans - Ich glaube, ich habe diesen Mangel im zweiten Abschnitt meiner Antwort angesprochen. – Toby

2

Die zuvor akzeptierte Antwort ab 2010 kann zu der Zeit richtig gewesen, aber bitte von PCI DSS 3.0 Abschnitt 6.5, bewusst sein, in dem es heißt:

Zug Entwickler in sicheren Codierungstechniken, einschließlich, wie gemeinsam zu vermeiden Sicherheitslücken zu codieren und zu verstehen, wie sensible Daten im Speicher verarbeitet werden.

Letztendlich geht es darum, sich an die Best Practices der Branche zu halten.

Angesichts der bekannten Verstöße in den letzten Jahren, in denen sensible Daten (einschließlich Kreditkarteninformationen) von Malware, Angreifern usw. erfasst werden, wird mehr Wert darauf gelegt, vertrauliche Informationen auch im Speicher zu sichern.

Verwenden Sie nach Möglichkeit SecureString.

Wo es nicht möglich ist, nur verstehen, was Sie zu tun haben. Da Strings unveränderlich sind und man sich nicht immer auf die Garbage-Collection verlassen kann, muss man nur mit dem arbeiten, was man hat. Eine Methode, über die ich gelesen habe, besteht darin, den String in einen BSTR zu verwandeln, ihn in einen gepinnten String zu kopieren, dann werden sowohl der BSTR als auch der gepinnte String nach der Verwendung auf Null gesetzt. Es fühlt sich ein wenig "hacky" an, aber es ist besser, als überhaupt nichts zu tun.

Wenn Sie die Kreditkartennummer rein innerhalb einer Winform-App erfassen, ist es sehr machbar, die Kartennummer im Speicher zu behalten.

Mit einer ASP.NET-Web-App, aber ich bin mir nicht sicher ... Ich habe es nicht versucht, aber die general consensus auf SO scheint es ist es nicht wert. Darüber hinaus erwähnt MSDN ASP.NET-Anwendungen speziell, indem Sie sagen:

Verwendung der SecureString-Klasse ist in ASP weniger geeignet.NET Anwendungen. Es ist unwahrscheinlich, dass Sie Daten von einer Webseite extrahieren können, die vertrauliche Daten enthält (z. B. eine Kreditkartennummer) und in einem SecureString platzieren, ohne dass es bereits das Zwischensystem durchlaufen hat. String Objekte

Sie sind wahrscheinlich mit Ihrem Projekt fertig, aber hoffentlich wird dies anderen helfen.