Aller au contenu

Crypté

Ormar vous offre un moyen de chiffrer uniquement les champs de votre base de données. le backend de chiffrement fourni permet un chiffrement unidirectionnel (backend HASH) ainsi qu 'un chiffrement/déchiffrement bidirectionnel (backend FERNET).

!!!Attention Veuillez noter que pour que le chiffrement fonctionne, vous devez installer un package de chiffrement optionnel.

1
Vous pouvez le faire manuellement `pip install cryptography` ou avec l'ordre par `pip install ormar[crypto]`

Attention, ajouter encrypt_backend modifie le type de colonne de la base de données en TEXT, ce qui doit être reflété dans db via une migration (alambic) ou une modification manuelle.

Définir le Field Encryption

Pour chiffrer un champ, vous devez passer au moins les paramètres encrypt_secret et encrypt_backend.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
base_ormar_config = ormar.OrmarConfig(
    Metadata= métadonnée
    database=database
)

Filtre de classe (modèle ormar):
    ormar_config = base_ormar_config.copy()

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100,
                             encrypt_secret="secret123",
                             encrypt_backend=ormar.EncryptBackends.FERNET)

!!!vous avertit que vous pouvez chiffrer tous les types de champs, à l'exception de la colonne primary_key et de la famille Off (ForeignKey et ManyToMany).

Backend disponible

Le hash

HASH est un hachage à sens unique (comme un mot de passe) qui n'est jamais déchiffré lorsqu 'il est récupéré.

Pour le configurer, passez la valeur backend appropriée.

1
2
3
4
#repos de la définition du modèle
mot de passe: str = ormar.String(max_length=128,
                         encrypt_secret="secret123",
                         encrypt_backend=ormar. cryptBackends.HASH)

Notez que puisque ce backend ne déchiffre jamais les valeurs stockées, il ne fonctionne que pour les champs de chaîne. le hachage utilisé est un hachage sha512, donc la longueur du champ doit être>=128.

Attention, dans le backend HASH, vous pouvez filtrer par valeur complète, mais les filtres tels que contains ne fonctionneront pas car les valeurs chiffrées sont comparées.

!!!note Notez que l'encrypt_secret fourni est d'abord haché et utilisé comme sel, donc pour comparer avec les chaînes stockées, vous devez recréer cette étape. order_by ne fonctionnera pas car les chaînes chiffrées sont comparées, vous ne pouvez donc pas trier de manière fiable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Hash de classe (modèle ormar):
    ormar_config = base_ormar_config.copy(tablename="haches")

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=128,
                             encrypt_secret="udxc32",
                             encrypt_backend=ormar. cryptBackends.HASH)


await Hash(nom ='test1').save()

# note les étapes pour récupérer la valeur stockée
#Vous pouvez utiliser aussi le paquet de cryptographie pour introduire du hachlib
secret = hashlib.sha256("udxc32".encode()).digest()
secret = base64.urlsafe_b64encode(secret)
hashed_test1 = hashlib.sha512(secret + 'test1'.encode()).hexdigest()

#valeur complète comparaison travaux
hash1 = await Hash.objects.get(nom ='test1')
assert hash1.name == hashed_test1

#mais comparaison partielle ne doit pas (les lignes hachées sont comparées)
Avec pytest.raises(NoMatch):
    await Filter.objects.get(name__icontains ='test')

Fernet est une

FERNET est un backend de chiffrement/décryptage bidirectionnel

Pour le configurer, passez la valeur backend appropriée.

1
2
3
#repos de la définition du modèle
année: int = ormar.Integer(encrypt_secret="secret123"),
                          encrypt_backend=ormar.EncryptBackends.FERNET)

Les valeurs sont chiffrées en route vers le côté de la base de données et déchiffrées en sortant. peut être utilisé pour tous les types, car la valeur de retour est analysée dans le type python correspondant.

Attention!!! Attention, dans le backend FERNET, vous perdez complètement la possibilité de filtrer, car une partie de la valeur chiffrée est horodatée. order_by aussi, car les chaînes chiffrées sont comparées, donc vous ne pouvez pas trier de manière fiable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Filtre de classe (modèle ormar):
    ormar_config = base_ormar_config.copy()

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100,
                             encrypt_secret="asd123",
                             encrypt_backend=ormar.EncryptBackends.FERNET)

await Filter(nom ='test1').save()
await Filter(nom ='test1').save()

#valeurs sont proprement encryptées et plus tard décryptées
filters = await Filter.objects.all()
assert filters[0].name == filters[1].name == 'test1'

#Mais vous ne pouvez filtrer à toutes les parties since du hachage fernet est un timestamp
#Qui signifie que même si vous encryptez la même chaîne de 2 temps, il sera différent
Avec pytest.raises(NoMatch):
    await Filter.objects.get(nom ='test1')

Customisation du backend

Si vous souhaitez prendre en charge d'autres types de cryptage (par exemple AES), vous pouvez fournir votre propre EncryptionBackend.

Pour configurer le backend, tout ce que vous devez faire est de sous-classer la classe ormar.fields.EncryptBackend et de fournir le backend requis.

Un exemple de backend virtuel (qui ne fait rien) ressemblerait à ceci:

1
2
3
4
5
6
7
8
9
class DummyBackend(ormar.fields.EncryptBackend):
    def _initialize_backend(self, secret_key: octets) -> None:
        par PASS

    def encrypt(self, valeur: Any) -> str:
        retour valeur

    def decrypt(self, valeur: Any) -> str:
        retour valeur

Pour utiliser ce backend, définissez encrypt_backend sur CUSTOM et fournissez votre backend comme argument via encrypt_custom_backend.

1
2
3
4
5
6
7
8
9
Filtre de classe (modèle ormar):
    ormar_config = base_ormar_config.copy()

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100,
                             encrypt_secret="secret123",
                             encrypt_backend=ormar.EncryptBackends.CUSTOM,
                             encrypt_custom_backend=DummyBackend
                             )