LiveHelp
:: О компании :: Портфолио :: Основные услуги :: Дополнительные услуги :: Информация

Шифрование средствами СУБД либо средствами Python в Django

Иногда бывает нужно реализовать шифрование данных при работе с базой данных. В системе Django работа с базой данных довольно специфична, SQL запросы выполняются через ОРМ и не сразу можно понять, как получить доступ непосредственно к синтаксису запроса. Естественно мы хотим получить вместе с шифрованием полный функционал работы с ОРМ Django, следовательно нам не подойдет вариант с использованием своих запросов в обход ОРМ модели.

Шифрование методами MySQL выглядит приблизительно так:

INSERT INTO table VALUES ('not encrypted value', AES_ENCRYPT( 'encrypted value', 'secret key value'));

Шифрования через ОРМ модель Django методами MySql реализуется следующим образом:

class Employee(models.Model):
   social_security_number = models.CharField(max_length=32)

   def _get_ssn(self):
       cursor = connection.cursor()
       cursor.execute("SELECT AES_DECRYPT(UNHEX(social_security_number), %s) as ssn FROM tablename WHERE id=%s", [settings.SECRET_KEY, self.id])
       return cursor.fetchone()[0]

   def _set_ssn(self, ssn_value):
       cursor = connection.cursor()
       cursor.execute("SELECT HEX(AES_ENCRYPT(%s, %s)) as ssn", [ssn_value, settings.SECRET_KEY])
       self.social_security_number = cursor.fetchone()[0]

   ssn = property(_get_ssn, _set_ssn)

# Результат работы скрипта
>>> from foo.bar.models import Employee
>>> p=Employee.objects.create(ssn='123-45-6789')
>>> p.ssn
'123-45-6789'

А вот, что мы получим в базе MySQL:

mysql> select * from foo_employee;
+----+----------------------------------+
| id | social_security_number           |
+----+----------------------------------+
| 31 | 41DF2D946C9186BEF77DD3307B85CC8C |
+----+----------------------------------+
1 row in set (0.00 sec)

Кроме этого есть возможность шифровать данные методами Python, см. пример:

from django.db import models
from Crypto.Cipher import Blowfish
from django.conf import settings
import binascii

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'

Вот, что получим в MySql:

$ mysql -e "SELECT * FROM django_sandbox.field_encryption_person"
#+----+------------+-----------+----------------------------------+
#| id | first_name | last_name | social_security_number           |
#+----+------------+-----------+----------------------------------+
#|  3 | Billy      | Barou     | 94ec660c832c95b31500618a5ffee60f |
#+----+------------+-----------+----------------------------------+
Назойливая реклама:

Зарабатывать на разнице валют в форекс это очень интересное занятие чем то похожее на азартные игры. И если вы не хотите спустить все свои деньги на бирже, тогда посетите форекс клуб, где вам помогут держать "нос по ветру" финансовых течений на бирже.

Share this

Мы на других сайтах

F P V