Wie kann ich wissen, mit welchem ​​Hashing-Algorithmus SQL Server die verschlüsselten Daten bei Verwendung der Funktion DECRYPTBYPASSPHRASE entschlüsselt hat?

12

Meine Frage bezieht sich auf das folgende Experiment mit zwei Instanzen:

SQL Server 2017 Express-Instanz (Microsoft SQL Server 2017 (RTM-CU16))
SQL Server 2014 Express-Instanz (Microsoft SQL Server 2014 (SP2-CU18))

Ich habe die Funktion ENCRYPTBYPASSPHRASE verwendet , um einen Text zu verschlüsseln, und das Ergebnis als @ciphertext für DECRYPTBYPASSPHRASE verwendet . Das Ergebnis meiner Tests waren folgende:

Ergebnistabelle

Nach diesem Microsoft-Fix ,

[...] SQL Server 2017 verwendet den SHA2-Hashing-Algorithmus, um die Passphrase zu hashen. SQL Server 2016 und frühere Versionen von SQL Server verwenden den SHA1-Algorithmus, der nicht mehr als sicher gilt.

Aber woher weiß es, mit welchem ​​Algorithmus Daten verschlüsselt wurden, wenn für die Funktion DECRYPTBYPASSPHRASE kein diesbezügliches Argument vorliegt? Ist es Teil der verschlüsselten Daten?

Aufgrund der Ergebnisse meiner Tests würde ich vermuten, dass SQL Server immer die neuere Version des auf der Instanz verfügbaren Algorithmus zum Verschlüsseln von Daten verwendet, aber alle Algorithmen versucht, Daten zu entschlüsseln, bis sie einen finden, der passt oder NULL zurückgibt, wenn kein entsprechender Algorithmus gefunden wird . Es ist jedoch nur eine Vermutung, da ich keine Möglichkeit gefunden habe, zu überprüfen, mit welchem ​​Hashing-Algorithmus SQL Server die verschlüsselten Daten entschlüsselt hat.

Ronaldo
quelle

Antworten:

14

Aber woher weiß es, mit welchem ​​Algorithmus Daten verschlüsselt wurden, wenn für die Funktion DECRYPTBYPASSPHRASE kein diesbezügliches Argument vorliegt? Ist es Teil der verschlüsselten Daten?

Ja, genau richtig.

Ich werde Folgendes für die Ausgabe verwenden:

DECLARE @Data VARBINARY(MAX)
DECLARE @Text NVARCHAR(MAX) = N'I''ll get you, and your little dog too!'
DECLARE @Phrase NVARCHAR(100) = N'Fly My Pretties!'

SELECT @Data = ENCRYPTBYPASSPHRASE(@Phrase, @Text)

SELECT @Data AS [Encrypted_Data]

SELECT CAST(DECRYPTBYPASSPHRASE(@Phrase, @Data) AS NVARCHAR(MAX))

Wenn ich dies auf meiner 2014-Instanz ausführe, erhalte ich Folgendes für Encrypted_Data: 0x01000000E565142762F62...

Wenn ich dies auf meiner 2017-Instanz ausführe, erhalte ich Folgendes für Encrypted_Data: 0x020000004D261C666204F...

Was herausspringen sollte, ist die Präambel, in der Sie sehen können, dass die Instanz 2014 beginnt 0x01und die Instanz 2017 mit beginnt 0x02. Dies ist die Versionierung des verwendeten Verschlüsselungstyps. Beachten Sie, dass es mehr als nur dies gibt, es jedoch nicht erforderlich ist, auf diese Details für die Zwecke dieser Antwort einzugehen, und dass es auch nicht öffentlich bekannt sein muss.

SQL Server 2017 versteht 0x01und 0x02weil es neu ist und die neuen Dinge kennt. SQL Server 2014 versteht nur, 0x01weil es älter ist und keine der neuen Dinge kennt, da die neuen Dinge nicht zurückportiert wurden.

[...] SQL Server 2017 verwendet den SHA2-Hashing-Algorithmus, um die Passphrase zu hashen. SQL Server 2016 und frühere Versionen von SQL Server verwenden den SHA1-Algorithmus, der nicht mehr als sicher gilt.

Dies ist nicht dasselbe, hat jedoch im Allgemeinen damit zu tun, dass symmetrische Schlüssel in beiden Versionen mit demselben Initialisierungsvektor erstellt werden. Ich habe darüber gebloggt, als 2017 herauskam, und es wurde etwas später mit dem Trace-Flag behoben, das verwendet werden muss, während in Ihrer Frage für 2017 kein Trace-Flag erforderlich ist, um die 2014-Daten wie gezeigt zu lesen.

Sean Gallardy
quelle
Hallo Sean. Könnten Sie in Ihrer Antwort detailliertere Informationen zum Trace-Flag angeben?
Konstantin Taranov