Source code for pangea.core.encrypted_fields

"""Encrypted Model Fields.

From https://github.com/defrex/django-encrypted-fields with modifications.
"""

import types

from django.db import models
from django.conf import settings

from itertools import cycle
import base64


[docs]class EncryptedFieldException(Exception): pass
[docs]class XOR: """Does this count as rolling my own crypto? I can't find any good python libraries and XOR is dummy simple. """ prefix = 'ENCRYPTED--'
[docs] @staticmethod def key(): mykey = settings.SECRET_KEY assert mykey return mykey
[docs] @staticmethod def encrypt(data): key = XOR.key() xored = [chr(ord(x) ^ ord(y)) for (x, y) in zip(data, cycle(key))] xored = ''.join(xored) xored = xored.encode('utf-8') xored = base64.standard_b64encode(xored) xored = xored.decode('utf-8') xored = XOR.prefix + xored return xored
[docs] @staticmethod def decrypt(data): assert data.startswith(XOR.prefix) data = data[len(XOR.prefix):] key = XOR.key() data = data.encode('utf-8') data = base64.standard_b64decode(data) xored = [chr(x ^ ord(y)) for (x, y) in zip(data, cycle(key))] xored = ''.join(xored) return xored
[docs]class EncryptedString: """Ensures that we will need to manually call `decrypt` to access the plain text.""" def __init__(self, value): self.value = value def __eq__(self, other): return self.value == other def __str__(self): return str(self.value)
[docs] def decrypt(self): return XOR.decrypt(self.value)
[docs]class EncryptedTextField(models.Field):
[docs] def from_db_value(self, value, expression, context): value = EncryptedString(value) return self.to_python(value)
[docs] def to_python(self, value): if value is None or isinstance(value, EncryptedString): return value return value
[docs] def get_prep_value(self, value): if value is None or value == '': return value if isinstance(value, EncryptedString): return str(value) value = XOR.encrypt(value) return value