2010-08-24 8 views
10

Ich bin auf der Suche nach SQL-Spalten-Level-Verschlüsselung mit symmetrischen Schlüsseln. Die ersten Schritte, die zum Erstellen des Datenbankhauptschlüssels, der Zertifikate und der symmetrischen Schlüssel erforderlich sind, scheinen einfach zu sein, und ich habe das Verschlüsseln/Entschlüsseln von Daten mit Symmetric Keys erfolgreich getestet.SQL verschlüsselte Spalten in WHERE-Klausel

Sobald jedoch die Daten verschlüsselt sind, weiß ich nicht, wie man es am besten abfragt. Z.B.

SELECT PlainTextA, PlainTextB, PlainTextC 
WHERE CONVERT(varchar, DECRYPTBYKEY(EncyptedColumn)) = @SearchTerm 

würde sicherlich zu einem vollständigen Tabellenscan führen?

Eine andere Option, die ich dachte, könnte funktionieren, verschlüsselt die Suchkriterien zuerst z.

SELECT PlainTextA, PlainTextB, PlainTextC 
WHERE EncyptedColumn = ENCRYPTBYKEY(KEY_GUID('KeyName'), @SearchTerm) 

aber dies funktioniert nicht, da der verschlüsselte Wert immer unterschiedlich ist.

Alle Vorschläge würden sehr geschätzt werden.

Antwort

10

Der typische Weg ist zu speichern, sowohl den verschlüsselten Wert und eine Einweg-Hash-Wert des Wert. Wenn Sie einen bestimmten Wert suchen, suchen Sie den Hashwert. So können Sie effizient abfragen können, w/o jede Zeile, um den Wert, den Sie interessiert sind zu finden zu entschlüsseln, mit:

create table Table (
EncryptedColumn varbinary(max), 
HashValue binary(20), 
PlainA int, 
PlainB varchar(256), 
PlainC Datetime); 

create index ndxTableHash on Table(HashValue); 

select PlainA, plainB, PlainC 
from table 
where HashValue = HashBytes('SHA1', @searchTerm); 

Theoretisch Sie einen Hash-Konflikt einmal in einem blauen Mond haben können, sein paranoid-safe Sie eine doppelte Kontrolle auf der entschlüsselten Spalte hinzufügen:

select PlainA, plainB, PlainC 
from table 
where HashValue = HashBytes('SHA1', @searchTerm) 
and DecryptByKey(..., EncryptedColumn) = @searchTerm; 

auch Indexing encrypted data und SQL Server 2005: searching encrypted data sehen.

+2

Btw, die eine Sache, die Sie absolut ** tun nicht tun, ist, den Hash mit einem zeilenspezifischen Wert (PK) zu salzen: Sie würden genau auf Platz 1 zurück sein, nicht wissend, was man sucht. Für diese Szenarien können Sie * den Hash mit einem globalen * Site-Wert abgleichen. Dies reicht aus, um Rainbow-Tabellen-Angriffe zu verhindern, aber die Daten sind durchsuchbar. Beachten Sie jedoch, dass zwei verschiedene Zeilen mit identischem Inhalt * denselben Hash-Wert haben, so dass Sie einige Informationen offen legen, aber dies ist die Definition, die Daten suchbar zu machen. –

+0

"Beachten Sie, dass zwei verschiedene Zeilen mit identischem Inhalt den gleichen Hash haben" - das war mein Hauptanliegen bei der Verwendung von Hashing, da es die Sicherheitsstufe reduziert, die Tabelle, an der ich arbeite, wird jedoch 4 bis 5 verschlüsselte Spalten haben Ich füge nur eine entsprechende Hash-Spalte für eine von diesen hinzu, dann kann sie akzeptabel sein. –

+0

Beachten Sie, dass Hash-Kollision in der Tabelle Geburtstag-Angriff (Meet-in-the-Middle) unterliegt, also ist deutlich höher als Intuition würde es sagen. Immer noch hat SHA1 einen ziemlich großen Adressraum bei 20 Bytes. –

2

Eine Option, die Sie haben, ist eine neue Spalte der Tabelle hinzufügen (oder eine WITH SCHEMABINDING Ansicht mit einer berechneten Spalte darin haben, und indizieren Sie das) mit einer Einweg-HASH des Suchwerts. Es muss kein starker Hash sein - something as simple as CHECKSUM will work. Dann hashst du den Suchwert in deiner Suche und filterst ihn nach dem Hash, der indiziert ist. Auf diese Weise können Sie etwas durchsuchbar und indizierbar machen, ohne den Wert selbst anzuzeigen.

Allerdings, wenn es eine andere Art und Weise ist dies direkt zu tun, würde ich gerne wissen, was es ist :)

+0

Danke für die Antwort und den Link. Ich nehme an, es wäre auch am besten, den Wert vor dem Hashing zu salzen, indem man den Primärschlüssel als Salz verwendet? –

+1

Nein - du wirst den Wert nicht salzen wollen, es sei denn, wie Remus sagt, es ist eine Art "globales Salz", und dann ist es nicht wirklich ein Salz. Wenn Sie Ihre Werte abgleichen, wird Ihre Indexsuche unmöglich, da das Salz für jede Zeile unterschiedlich ist. – SqlRyan

-1

Eine weitere Option besteht darin, eine View zu verwenden, die eine Spalte mit entschlüsseltem Wert enthält und Datensätze entsprechend findet.

SELECT PlainTextA, PlainTextB, PlainTextC from TheView 
WHERE DecryptedColumn = @SearchTerm