使用pycryptodome aes-256 gcm加密的django模型字段。
django-searchable-encrypted-fields的Python项目详细描述
django可搜索加密字段
如果您想在“应用程序内”加密模型字段数据(即在将其发送到数据库之前),请使用此软件包。
为什么是另一个加密字段包?
- 我们使用带有gcm模式的aes-256加密(通过pycryptodome库)。
- 有一个django命令可以轻松地生成适当的加密密钥。
- 您也可以使用searchfield进行“精确”搜索查找。
安装和设置
$ pip install django-searchable-encrypted-fields
# in settings.pyINSTALLED_APPS+=["encrypted_fields"]# A list of hex-encoded 32 byte keys# You only need one unless/until rotating keysFIELD_ENCRYPTION_KEYS=["f164ec6bd6fbc4aef5647abc15199da0f9badcc1d2127bde2087ae0d794a9a0b"]
简介
这个包为django提供了两种类型的模型字段。
- 一系列encryptedfield类,它们可以自己使用,工作方式与常规的django类类似。内容是透明加密/解密的。
- 可以与任何加密字段一起使用的searchfield。值用
hash_key
表示,然后用sha256散列,然后再存储在单独的字段中。这意味着可以执行“精确”搜索。
这可能是最好的例子:
使用独立加密字段
fromencrypted_fieldsimportfieldsclassPerson(models.Model):favorite_number=fields.EncryptedIntegerField(help_text="Your favorite number.")
您可以使用所有常用的字段参数并像平常一样添加验证器。 但是,请注意,不支持主密钥、唯一索引和数据库索引,因为它们对加密数据没有意义。
将搜索字段与加密字段一起使用
classPerson(models.Model):_name_data=fields.EncryptedCharField(max_length=50,editable=False)name=fields.SearchField(encrypted_data_field="_name_data",hash_key="f164ec6bd...7ae0d794a9a0b")favorite_number=fields.EncryptedIntegerField()city=models.CharField(max_length=255)# regular Django model field
然后您可以像这样使用它:
# "Jo" is hashed and stored in 'name' as well as symmetrically encrypted and stored in '_name_data'Person.objects.create(name="Jo",favorite_number=7,city="London")person=Person.objects.get(name="Jo")assertperson.name=="Jo"assertperson.favorite_number==7person=Person.objects.get(city="London")assertperson.name=="Jo".# the data is taken from '_name_data', which decrypts it first.
您可以安全地进行如下更新:
person.name="Simon"person.save()
但是当使用update()
时,需要为两个字段提供值:
Person.objects.filter(name="Jo").update(name="Bob",_name_data="Bob")
searchfield从其关联的encryptedfield继承验证器和formfield(小部件)。所以:
- 不要向searchfields添加验证器或表单小部件(它们将被忽略),而是将它们添加到关联的encryptedfield。
- 不要在表单中包含encryptedfield,而只显示searchfield。
包括加密字段类
包括以下各项:
"EncryptedFieldMixin","EncryptedTextField","EncryptedCharField","EncryptedEmailField","EncryptedIntegerField","EncryptedDateField","EncryptedDateTimeField","EncryptedBigIntegerField","EncryptedPositiveIntegerField","EncryptedPositiveSmallIntegerField","EncryptedSmallIntegerField",
注意,虽然未经测试,但您应该能够扩展其他常规django模型字段类,如:
classEncryptedIPAddressField(EncryptedFieldMixin,models.GenericIPAddressField):pass
如果你做这件事有问题,请告诉我们。
生成加密密钥
您可以使用包含的django管理命令,该命令将向终端打印适当的十六进制编码密钥,准备在settings.FIELD_ENCRYPTION_KEYS
中使用,或者用作搜索字段的哈希键:
$ python manage.py generate_key
注意:加密密钥必须是十六进制编码的32字节
important:为每个搜索字段使用不同的哈希键值,并确保它们与settings.FIELD_ENCRYPTION_KEYS
中的任何键不同。
旋转加密密钥
如果要旋转加密密钥,只需在settings.FIELD_ENCRYPTION_KEYS
前添加一个新密钥。这个新密钥(列表中的第一个)将用于加密/解密所有数据。如果解密数据失败(因为它是用旧密钥加密的),则会尝试列表中的每个密钥。
相容性
django-searchable-encrypted-fields
在python(3.6,3.7)上用django(2.1,2.2)使用sqlite和postgresql进行测试。
测试覆盖率为96%。