Login

Transparent encryption for model fields

Author:
shadfc
Posted:
June 26, 2008
Language:
Python
Version:
.96
Tags:
database encryption
Score:
5 (after 5 ratings)

Here's a simple way to transparently encrypt a field (just repeat the idiom for more than one) so that it is not stored plaintext in the database. This might be useful for social security numbers, etc.

The storage size for the ciphertext depends on which algorithm you use. Blowfish here requires 32 characters to store an encrypted 16 characters. Note also that Blowfish requires a block size of a multiple of 8, so that is what the repeat in the _set_ssn() is all about.

The Crypto module is from http://www.amk.ca/python/code/crypto.html

I make no claims as to how secure this scheme is overall, comments on this are welcome.

 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
32
33
34
35
36
37
38
# demo model
from django.db import models
from Crypto.Cipher import Blowfish
from django.conf import settings
import binascii

# Create your models here.
class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    social_security_number = models.CharField(max_length=32)

    def _get_ssn(self):
        enc_obj = Blowfish.new( settings.SECRET_KEY )
        return u"%s" % enc_obj.decrypt( binascii.a2b_hex(self.social_security_number) ).rstrip()

    def _set_ssn(self, ssn_value):
        enc_obj = Blowfish.new( settings.SECRET_KEY )
        repeat = 8 - (len( ssn_value ) % 8)
        ssn_value = ssn_value + " " * repeat
        self.social_security_number = binascii.b2a_hex(enc_obj.encrypt( ssn_value ))

    ssn = property(_get_ssn, _set_ssn)



# testing
>>> Person.objects.all().delete()
>>> p = Person.objects.create(first_name='Billy', last_name='Barou', ssn='123-12-1234')
>>> p.ssn
u'123-12-1234'

#sandbox$ mysql -e "SELECT * FROM django_sandbox.field_encryption_person"
#+----+------------+-----------+----------------------------------+
#| id | first_name | last_name | social_security_number           |
#+----+------------+-----------+----------------------------------+
#|  3 | Billy      | Barou     | 94ec660c832c95b31500618a5ffee60f | 
#+----+------------+-----------+----------------------------------+

More like this

  1. Transparently encrypt ORM fields using OpenSSL (via M2Crypto) by ncoghlan 4 years, 1 month ago
  2. Encryption Fields by zbyte64 6 years, 11 months ago
  3. JsonObjectField by wattsmartin 4 years, 8 months ago
  4. Saving passwords for other services (semi-)securely in a database by equanimity 6 years, 6 months ago
  5. Database file storage by powerfox 6 years, 6 months ago

Comments

Please login first before commenting.