Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Laravel AES-256-Verschlüsselung und MySQL

Aktualisieren

PR 31721 wurde in Laravel 7.0.8 zusammengeführt, wodurch die Escape-Schrägstriche in der JSON-Codierung behoben werden. Zuvor würde die Verschlüsselung derselben Daten zu Ergebnissen mit variabler Größe führen. Ab Version 7.0.8 erhalten Sie durch die Verschlüsselung derselben Daten jedes Mal dieselbe Größe.

TL;DR:

Die Verschlüsselungsmethode von Laravel gibt eine Zeichenfolge zurück, daher sollte der Datentyp je nach Größe der zu verschlüsselnden Daten eine Varchar- oder Textvariation sein.

Um die ungefähre Größe zu bestimmen, können Sie die folgende Reihe von Berechnungen verwenden:

Laravel>=7.0.8

Lassen Sie a =die Größe der serialisierten unverschlüsselten Daten (strlen(serialize($data)) )
Lassen Sie b =a + 16 - (a MOD 16) (Größe der verschlüsselten Daten berechnen)
Lassen Sie c =(b + 2 - ((b + 2) MOD 3)) / 3 * 4 (Größe der base64-kodierten Daten berechnen)
Lassen Sie d =c + 117 (Größe von MAC, IV und json-Codierung hinzufügen)
Lassen Sie e =(d + 2 - ((d + 2) MOD 3)) / 3 * 4 (Berechnen Sie die Größe der base64-codierten Daten)

Obwohl der Wert nicht deterministisch ist, ist die Größe des Ergebnisses. Wenn Sie beispielsweise eine 9-stellige Sozialversicherungsnummer verschlüsseln, ist das Ergebnis immer 216 Zeichen.

Laravel <7.0.8

Lassen Sie a =die Größe der serialisierten unverschlüsselten Daten (strlen(serialize($data)) )
Lassen Sie b =a + 16 - (a MOD 16) (Größe der verschlüsselten Daten berechnen)
Lassen Sie c =(b + 2 - ((b + 2) MOD 3)) / 3 * 4 (Größe der base64-kodierten Daten berechnen)
Lassen Sie d =c + 117 + 8 + ((c + 2 - ((c + 2) MOD 3)) / 3) (Fügen Sie die Größe der MAC-, IV- und json-Codierung hinzu, plus zusätzlichen Puffer für potenziell maskierte Schrägstriche)
Lassen Sie e =(d + 2 - ((d + 2) MOD 3)) / 3 * 4 (Berechnen Sie die Größe der base64-codierten Daten)

Wenn Sie beispielsweise eine 9-stellige Sozialversicherungsnummer verschlüsseln würden, wäre das Ergebnis mindestens 216 Zeichen und höchstens 308 Zeichen (obwohl dies wahrscheinlich eine statistische Unmöglichkeit ist). Wenn Sie eine Schleife mit mehr als 100.000 Verschlüsselungen ausführen, werden Sie feststellen, dass die Größe normalerweise im Bereich von 216 bis 224 liegt. Die oben angegebene Formel würde Ihnen sagen, dass Sie Ihr Feld auf 248 Zeichen setzen sollten, was ein gesunder Puffer über dem erwarteten Bereich ist, aber statistisch nicht unmöglich zu erreichen.

Details:

Der von der encrypt-Methode zurückgegebene Wert ist nicht nur der verschlüsselte Text, sondern eine base64-codierte Darstellung eines json-codierten Payload-Arrays, das (1) den base64-codierten verschlüsselten Wert der serialisierten Daten, (2) den base64-codierten Initialisierungsvektor ( IV) und (3) den Message Authentication Code (MAC). Um also die Größe des benötigten Felds zu bestimmen, müssen Sie die maximale Größe der zu codierenden Daten kennen und dann etwas mehr Platz für diese zusätzlichen Informationen hinzufügen, die in die zurückgegebene Zeichenfolge eingefügt werden.

Lassen Sie uns zunächst die maximale Größe Ihres verschlüsselten Werts berechnen. Da Ihr Verschlüsselungsalgorithmus (AES-256-CBC) eine Blockchiffre ist, lässt sich dies ziemlich einfach mit einer Formel erledigen. AES verwendet 16-Byte-Blöcke und erfordert mindestens ein Byte zum Auffüllen, sodass die Größe des verschlüsselten Werts das nächste Vielfache von 16 ist. Wenn Ihre Originaldaten also 30 Byte umfassen, sind Ihre verschlüsselten Daten 32 Byte. Wenn Ihre ursprünglichen Daten 32 Bytes groß sind, sind Ihre verschlüsselten Daten 48 Bytes (da AES mindestens ein Byte zum Auffüllen benötigt, werden Ihre 32 Bytes zu 33, und das geht dann bis zum nächsten Vielfachen von 16 bis 48). Die Formel dafür wäre x + 16 - (x MOD 16) . Für 30 Bytes erhalten Sie also 30 + 16 - (30 MOD 16) = 32 .

Beachten Sie beim Berechnen der Größe des verschlüsselten Werts, dass die zu verschlüsselnden Daten zuerst serialisiert werden. Wenn Sie also beispielsweise eine Sozialversicherungsnummer verschlüsseln, besteht der einfache Wert nur aus 9 Zeichen, aber der serialisierte Wert besteht tatsächlich aus 16 Zeichen (s:9:"xxxxxxxxx";). ). Da der serialisierte Wert tatsächlich verschlüsselt ist und 16 Byte groß ist, beträgt die Größe des verschlüsselten Werts 32 Byte (16 + 16 - (16 MOD 16) = 32). ).

Darüber hinaus wird der openssl_encrypt Funktion gibt die verschlüsselten Daten bereits base64-kodiert zurück. Die Base64-Codierung erhöht die Größe des Werts um etwa 4/3. Für jeweils 3 Byte in den Originaldaten generiert die Base64-Codierung eine 4-Byte- (Zeichen-)Darstellung. Für das SSN-Beispiel beträgt das verschlüsselte Ergebnis also 32 Bytes. Bei der Übersetzung in base64 ergeben 32 Bytes (32 / 3) = 10.6 3-Byte-Segmente. Da base64 zum nächsten Byte auffüllt, nehmen Sie die Obergrenze und multiplizieren Sie mit 4, was 11 * 4 = 44 ergibt Byte. Unser ursprünglicher verschlüsselter 32-Byte-Wert wird also zu einer Zeichenfolge mit 44 Zeichen. Wenn Sie dafür eine Formel benötigen, können Sie (x + 2 - ((x + 2) MOD 3)) / 3 * 4 verwenden . Also (32 + 2 - ((32 + 2) MOD 3)) / 3 * 4 = 44 .

Die nächste Information ist der MAC. Der MAC ist ein SHA256-Hash-Wert, daher wissen wir, dass er 64 Zeichen lang sein wird.

Die letzte Information ist die IV. Die einfache IV besteht aus 16 zufälligen Bytes. Der im Payload-Array gespeicherte IV ist der base64-codierte Wert des einfachen IV. Wir können also die obige Formel verwenden, um die Größe des base64-codierten IV zu berechnen:(16 + 2 - ((16 + 2) MOD 3)) / 3 * 4 = 24 .

Diese drei Informationen werden in ein Array komprimiert und dann json_codiert. Aufgrund der JSON-Darstellung und der Namen der Werte im Array werden weitere 29 Bytes hinzugefügt.

Darüber hinaus werden in Laravel <7.0.8 alle Schrägstriche in den base64-codierten Daten mit Backslashes in der JSON-Zeichenfolge maskiert, sodass eine variable Anzahl von Bytes hinzugefügt wird, je nachdem, wie viele Schrägstriche vorhanden sind. Für das SSN-Beispiel gibt es 68 Zeichen base64-codierter Daten (44 für die verschlüsselten Daten, 24 für die IV). Nehmen wir an, die maximale Anzahl an Schrägstrichen beträgt wahrscheinlich etwa 1/3 der Ergebnisse oder etwa 23 zusätzliche Bytes. In Laravel>=7.0.8 werden diese Schrägstriche nicht maskiert, sodass keine zusätzlichen Bytes vorhanden sind.

Schließlich ist dieser json_encoded-Wert base64_encoded, was wiederum die Größe um einen Faktor von etwa 4/3 erhöht.

Um das alles zusammenzufassen, stellen wir uns noch einmal vor, Sie verschlüsseln eine Sozialversicherungsnummer. Der openssl_encrypt Das Ergebnis ist 44 Zeichen, der MAC 64 Zeichen, der IV 24 Zeichen und die json-Darstellung fügt weitere 29 Zeichen hinzu.

In Laravel <7.0.8 gibt es auch den Puffer von zusätzlichen 23 Zeichen. Das ergibt (44 + 64 + 24 + 29 + 23 = 184 ) Figuren. Dieses Ergebnis wird base64-kodiert, was uns ergibt ((184 + 2 - ((184 + 2) MOD 3)) / 3 * 4 = 248 ) Zeichen.

In Laravel>=7.0.8 gibt es keinen zusätzlichen Puffer. Das ergibt (44 + 64 + 24 + 29 = 161 ) Figuren. Dieses Ergebnis wird base64-kodiert, was uns ergibt ((161 + 2 - ((161 + 2) MOD 3)) / 3 * 4 = 216 ) Zeichen.