2010-12-01 3 views
1

est-ce possible?Django: recherche sur un EncryptedCharField (django-extensions), est-ce possible?

Pour un modèle avec EncryptedCharField nommé "prénom" je remarque que le champ ne décrypte pas lorsque je le recherche. Dans tous les autres cas, c'est bien. Cela ne fonctionne pas:

if form.is_valid(): 
    cd = form.cleaned_data 
    search_results = MyTable.objects.filter(first_name__icontains=cd['search_term']) 

est-ce intentionnellement ou est-ce que je fais quelque chose de mal? merci pour votre aide ...

Crypter le terme de recherche en premier, même si la valeur décryptée exacte, ne fonctionnerait pas car le chiffre ne sera pas le même que celui enregistré dans la base de données. Donc, cela ne fonctionnerait pas:

crypter = Crypter.Read(settings.ENCRYPTED_FIELD_KEYS_DIR) 
if form.is_valid(): 
    cd = form.cleaned_data 
    cipher = crypter.Encrypt(cd['search_term']) 
    search_results = MyTable.objects.filter(first_name__icontains=cipher) 
+0

Donc cela fonctionne-t-il pour 'first_name__istartswith = cd ['search_term']'? –

+0

Je suppose que ce n'est pas possible car avec toutes les autres fonctions de recherche, la valeur est probablement cryptée en premier, puis comparée à la valeur de la base de données. Cela fonctionnerait pour «_exact» à tout le moins. Je ne sais pas exactement comment cela fonctionnerait avec '_iexact' honnêtement, puisque la plupart des méthodes de chiffrement traiteront complètement' A' et 'a' complètement différemment. –

+0

Oui c'est ce que fait, EncryptedCharField's get_db_prep_value() encrypt la valeur et to_python() décrypte. Ils utilisent keyczar. Mais quand je teste dans un shell, crypter une valeur deux fois, en utilisant la même clé, ne génère pas le même chiffre. Mais bien sûr, le chiffrement décrypte toujours correctement. Donc __exact ne fonctionnerait pas, ni __istartswith. Bien qu'absurde, cela "fonctionne" si je ne crypte pas le chiffre et utilise une partie du chiffre stocké comme terme de recherche. – erikvw

Répondre

1

Quand quelque chose est crypté (ou tout au moins, lorsqu'il est fait correctement), il est impossible de gagner la valeur qui a été chiffré, sans connaître la valeur. Cela signifie que si vous pouvez vérifier très rapidement la valeur de dire un mot de passe, car l'utilisateur vous a donné la valeur du mot de passe, il est très difficile de trouver la valeur du mot de passe de la chaîne chiffrée. Cela fait partie du sujet P=NP.

Lorsque vous effectuez une recherche via MyTable.objects.filter(first_name=cipher), vous comparez simplement des chaînes cryptées, ce qui est correct. Cependant, lorsque vous essayez MyTable.objects.filter(first_name_icontains=cipher), vous demandez à django de déchiffrer toutes les valeurs, de les comparer, puis de retourner les résultats. Cependant, django ne peut pas faire cela, car personne ne sait quelle est la valeur du champ first_name décrypté. C'est par conception, car cela signifie que même si la base de données est compromise, les données sont sûres (c'est aussi pourquoi vous devez vous méfier de tout site ou organisation qui vous montrera votre mot de passe, car cela signifie qu'ils n'ont pas chiffré la valeur dans leur base de données). Dans l'ensemble, ne pas être en mesure de voir un mot de passe utilisateur est une bonne chose, et même si vous n'êtes pas d'accord, c'est un petit prix à payer pour une bonne sécurité.

+0

Je suis d'accord avec vous, mais j'ai besoin de crypter les noms et les identifiants personnels et maintenir la possibilité de rechercher et de commander sur ces valeurs ainsi que d'utiliser une contrainte UNIQUE. Tout ce qui semble ne pas fonctionner et peut-être pas pratique. Cela pourrait-il être un problème de "gestionnaire"? – erikvw

+0

La seule façon de faire cela est d'avoir un CharField, et tout d'abord enregistrer la chaîne cryptée brute non modifiée, puis stocker après (par exemple sous forme csv) toutes les combinaisons de lettres que vous voulez pouvoir rechercher. Donc 'foo' deviendrait' foo, fo, oo'. En faisant cela, vous diminuez considérablement la sécurité du système, dans la mesure où vous pourriez aussi bien ne pas les crypter. En bref, si vous avez besoin d'une recherche, vous ne pouvez pas chiffrer vos valeurs; les valeurs chiffrées partielles ne sont pas infixées de la valeur entièrement chiffrée. –

+0

ce sont de bons points.semble que ce que je voulais ne puisse être fait de manière utile. J'ai laissé tomber le champ crypté complètement. Merci!! – erikvw

1

Vous pouvez simplement stocker le hachage HMAC de la valeur dans un autre champ, puis recherchez-le.

+0

Non, l'OP ne peut pas faire cela pour toutes les données. S'il veut rechercher tout «John» sur la base de données, ce sera impossible. Un HMAC ne sera utile que pour rechercher des correspondances parfaites. – ThoriumBR

Questions connexes