Helpful exception for wrong keys
In case a user accidentally runs management scripts with a different secret key, they will get this error when trying to load a model that contains value encrypted with the other secret:
Input In [3], in <module>
----> 1 Account.objects.all()[1234]
File /usr/lib/python3.10/site-packages/django/db/models/query.py:321, in QuerySet.__getitem__(self, k)
319 qs = self._chain()
320 qs.query.set_limits(k, k + 1)
--> 321 qs._fetch_all()
322 return qs._result_cache[0]
File /usr/lib/python3.10/site-packages/django/db/models/query.py:1354, in QuerySet._fetch_all(self)
1352 def _fetch_all(self):
1353 if self._result_cache is None:
-> 1354 self._result_cache = list(self._iterable_class(self))
1355 if self._prefetch_related_lookups and not self._prefetch_done:
1356 self._prefetch_related_objects()
File /usr/lib/python3.10/site-packages/model_utils/managers.py:38, in InheritanceIterable.__iter__(self)
36 yield sub_obj
37 else:
---> 38 yield from iter
File /usr/lib/python3.10/site-packages/django/db/models/query.py:68, in ModelIterable.__iter__(self)
59 related_populators = get_related_populators(klass_info, select, db)
60 known_related_objects = [
61 (field, related_objs, operator.attrgetter(*[
62 field.attname
(...)
66 ])) for field, related_objs in queryset._known_related_objects.items()
67 ]
---> 68 for row in compiler.results_iter(results):
69 obj = model_cls.from_db(db, init_list, row[model_fields_start:model_fields_end])
70 for rel_populator in related_populators:
File /usr/lib/python3.10/site-packages/django/db/models/sql/compiler.py:1149, in SQLCompiler.apply_converters(self, rows, converters)
1147 value = row[pos]
1148 for converter in convs:
-> 1149 value = converter(value, expression, connection)
1150 row[pos] = value
1151 yield row
File /usr/lib/python3.10/site-packages/fernet_fields/fields.py:80, in EncryptedField.from_db_value(self, value, expression, connection, *args)
78 if value is not None:
79 value = bytes(value)
---> 80 return self.to_python(force_text(self.fernet.decrypt(value)))
File /usr/lib/python3.10/site-packages/cryptography/fernet.py:81, in Fernet.decrypt(self, token, ttl)
79 else:
80 time_info = (ttl, int(time.time()))
---> 81 return self._decrypt_data(data, timestamp, time_info)
File /usr/lib/python3.10/site-packages/cryptography/fernet.py:139, in Fernet._decrypt_data(self, data, timestamp, time_info)
136 raise InvalidToken
138 breakpoint()
--> 139 self._verify_signature(data)
141 iv = data[9:25]
142 ciphertext = data[25:-32]
File /usr/lib/python3.10/site-packages/cryptography/fernet.py:122, in Fernet._verify_signature(self, data)
120 h.verify(data[-32:])
121 except InvalidSignature:
--> 122 raise InvalidToken
InvalidToken:
It's not a very helpful message, instead we should check if the user has multiple FERNET_KEYS already, because if they haven't then the exception should mention "have you encrypted data with a different SECRET_KEY?"