python / expert
Snippet
Feld-Ebene Verschlüsselung über benutzerdefinierte Modellfeld-Deskriptoren
Python-Deskriptoren können mit benutzerdefinierten Django-Modellfeldern kombiniert werden, um eine transparente Verschlüsselung und Entschlüsselung auf Feldebene direkt bei Lese- und Schreibzugriffen auf Modellinstanzen durchzuführen.
snippet.py
python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from cryptography.fernet import Fernetfrom django.conf import settingsfrom django.db import modelsclass EncryptedFieldDescriptor:def __init__(self, field):self.field = fielddef __get__(self, instance, owner=None):if instance is None:return selfvalue = instance.__dict__.get(self.field.name)if value is None or not isinstance(value, str):return valueif value.startswith('gAAAAA'):cipher = Fernet(settings.SECRET_KEY.encode()[:32].ljust(32, b'='))return cipher.decrypt(value.encode()).decode()return valuedef __set__(self, instance, value):if value is not None and isinstance(value, str):cipher = Fernet(settings.SECRET_KEY.encode()[:32].ljust(32, b'='))encrypted = cipher.encrypt(value.encode()).decode()instance.__dict__[self.field.name] = encryptedelse:instance.__dict__[self.field.name] = valueclass EncryptedCharField(models.CharField):def contribute_to_class(self, cls, name, **kwargs):super().contribute_to_class(cls, name, **kwargs)setattr(cls, name, EncryptedFieldDescriptor(self))
django
Erklärung
1
class EncryptedFieldDescriptor:
Definiert einen benutzerdefinierten Python-Deskriptor zur Steuerung des Attributzugriffs auf Modellinstanzen.
2
def __get__(self, instance, owner=None):
Fängt Lesezugriffe ab und entschlüsselt Zeichenketten, wenn sie dem Verschlüsselungsmuster entsprechen.
3
def __set__(self, instance, value):
Fängt Zuweisungen ab und verschlüsselt Zeichenketten vor dem Speichern im __dict__ der Instanz.
4
def contribute_to_class(self, cls, name, **kwargs):
Verbindet die Deskriptor-Instanz während der Erstellung des Django-Modells mit der Modellklasse.