django处理pgcrypto postgres扩展的加密字段。
django-pgcrypto-fields的Python项目详细描述
django pgcrypto-pgcrypto-fields
django pgcrypto fields
是一个django
扩展,它依赖于pgcrypto
加密和解密字段的数据。
要求
- 带有pgcrypto的postgres
- 支持django 1.11.x到2.1.x
- 仅与Python 3兼容
此库的最新版本,支持django
1.8.x、1.9.x、1.10.x
wasdjango pgcrypto字段
2.2.0.
安装
安装软件包
pip install django-pgcrypto-fields
django设置
我们的库通过
在数据库设置中定义键。
在settings.py中:
importosBASEDIR=os.path.dirname(os.path.dirname(__file__))PUBLIC_PGP_KEY_PATH=os.path.abspath(os.path.join(BASEDIR,'public.key'))PRIVATE_PGP_KEY_PATH=os.path.abspath(os.path.join(BASEDIR,'private.key'))# Used by PGPPublicKeyField used by default if not specified by the dbPUBLIC_PGP_KEY=open(PUBLIC_PGP_KEY_PATH).read()PRIVATE_PGP_KEY=open(PRIVATE_PGP_KEY_PATH).read()# Used by TextHMACField and PGPSymmetricKeyField if not specified by the dbPGCRYPTO_KEY='ultrasecret'DIFF_PUBLIC_PGP_KEY_PATH=os.path.abspath(os.path.join(BASEDIR,'tests/keys/public_diff.key'))DIFF_PRIVATE_PGP_KEY_PATH=os.path.abspath(os.path.join(BASEDIR,'tests/keys/private_diff.key'))# And add 'pgcrypto' to `INSTALLED_APPS` to create the extension for# pgcrypto (in a migration).INSTALLED_APPS=('pgcrypto',# Other installed apps)DATABASES={# This db will use the default keys above'default':{'ENGINE':'django.db.backends.postgresql_psycopg2','NAME':'pgcryto_fields','USER':'pgcryto_fields','PASSWORD':'xxxx','HOST':'psql.test.com','PORT':5432,'OPTIONS':{'sslmode':'require',}},'diff_keys':{'ENGINE':'django.db.backends.postgresql_psycopg2','NAME':'pgcryto_fields_diff','USER':'pgcryto_fields_diff','PASSWORD':'xxxx','HOST':'psqldiff.test.com','PORT':5432,'OPTIONS':{'sslmode':'require',},'PGCRYPTO_KEY':'djangorocks','PUBLIC_PGP_KEY':open(DIFF_PUBLIC_PGP_KEY_PATH,'r').read(),'PRIVATE_PGP_KEY':open(DIFF_PRIVATE_PGP_KEY_PATH,'r').read(),},}
如果使用公钥加密,则生成GPG密钥
公钥将加密消息,私钥将 需要解密内容。以下命令是从 pgcrypto文档 (请参见使用gnupg生成pgp密钥)。
生成公钥和私钥(首选密钥类型为"dsa和elgamal"。)
$ gpg --gen-key $ gpg --list-secret-keys /home/bob/.gnupg/secring.gpg --------------------------- sec 2048R/21 2014-10-23 uid Test Key <example@example.com> ssb 2048R/42 2014-10-23 $ gpg -a --export 42 > public.key $ gpg -a --export-secret-keys 21 > private.key
从以前的版本升级到2.4.0
此库的2.4.0版本收到了一个较大的重写,以便支持 获取加密字段数据时自动解密以及筛选功能 在不使用旧的pgpcrypto聚合函数的加密字段上 在以前的版本中。
此库中的下列项已被删除,因此 您对这些项目的应用程序也需要删除:
管理器.pgpmanager
管理员pgpadmin
聚合。*
字段
django pgcrypto字段
有3种字段:
- 基于哈希的字段
- 公钥(PGP)字段
- 对称字段
基于哈希的字段
支持的基于哈希的字段是:
textDigestField
texthmacfield
textDigestField
在数据库中使用PTO函数
使用sha512
算法。
texthmacfield
在数据库中使用hmac
pgcrypto函数散列
使用键和sha512
算法。不过,这与摘要版本类似
哈希只能在知道密钥的情况下重新计算。这样可以防止有人改变
数据并更改哈希值以匹配。
公钥加密字段
支持的PGP公钥字段是:
charpgppublickeyfield
emailpgppublickeyfield
integerPGPublicKeyField
textpgppublickeyfield
datepgpppublickeyfield
datetimepgppublickeyfield
DecimalPGPublicKeyField
floatpgpppublickeyfield
TimePgpPublickeyField
公钥加密创建用公钥生成的令牌 对数据和私钥进行加密以解密。
公钥和私钥可以在设置中使用public_pgp_key
和
私钥
对称密钥加密字段
支持的PGP对称密钥字段是:
字符对称键域
电子邮件pgpSymmetyKeyField
integerpgpsymetrickeyfield
textpgpsymmetykeyfield
datepgpsymetykeyfield
dateTimePgpsSymmetyKeyField
decimalpgpsymetrickeyfield
floatpgpsymetykeyfield
TimePgpsSymmetyKeyField
使用settings.pgcrypto_key
加密和解密数据,它的作用类似于密码。
用法
模型定义
fromdjango.dbimportmodelsfrompgcryptoimportfieldsclassMyModel(models.Model):digest_field=fields.TextDigestField()digest_with_original_field=fields.TextDigestField(original='pgp_sym_field')hmac_field=fields.TextHMACField()hmac_with_original_field=fields.TextHMACField(original='pgp_sym_field')email_pgp_pub_field=fields.EmailPGPPublicKeyField()integer_pgp_pub_field=fields.IntegerPGPPublicKeyField()pgp_pub_field=fields.TextPGPPublicKeyField()date_pgp_pub_field=fields.DatePGPPublicKeyField()datetime_pgp_pub_field=fields.DateTimePGPPublicKeyField()time_pgp_pub_field=fields.TimePGPPublicKeyField()decimal_pgp_pub_field=fields.DecimalPGPPublicKeyField()float_pgp_pub_field=fields.FloatPGPPublicKeyField()email_pgp_sym_field=fields.EmailPGPSymmetricKeyField()integer_pgp_sym_field=fields.IntegerPGPSymmetricKeyField()pgp_sym_field=fields.TextPGPSymmetricKeyField()date_pgp_sym_field=fields.DatePGPSymmetricKeyField()datetime_pgp_sym_field=fields.DateTimePGPSymmetricKeyField()time_pgp_sym_field=fields.TimePGPSymmetricKeyField()decimal_pgp_sym_field=fields.DecimalPGPSymmetricKeyField()float_pgp_sym_field=fields.FloatPGPSymmetricKeyField()
加密
数据插入数据库时会自动加密。
示例:
>>> MyModel.objects.create(value='Value to be encrypted...')
如果使用original
属性,哈希字段可以自动更新哈希值。这个
属性允许您指示另一个字段名以作为哈希值的基础。
fromdjango.dbimportmodelsfrompgcryptoimportfieldsclassUser(models.Model):first_name=fields.TextPGPSymmetricKeyField(max_length=20,verbose_name='First Name')first_name_hashed=fields.TextHMACField(original='first_name')
在上面的示例中,如果指定可选的原始属性,则 将来自first_name model字段的未加密值作为输入值 创建哈希。如果未指定原始属性,则字段 将像现在一样工作,并保持向后兼容。
PGP字段
当访问模型实例的field name属性时,我们将获得 解密值。
示例:
>>> # When using a PGP public key based encryption
>>> my_model = MyModel.objects.get()
>>> my_model.value
'Value decrypted'
过滤加密值现在从2.4.0开始自动处理。和聚合
方法不再受支持,已从库中删除。
此外,自动解密还支持select_related()
型号。
fromdjango.dbimportmodelsfrompgcryptoimportfieldsclassEncryptedFKModel(models.Model):fk_pgp_sym_field=fields.TextPGPSymmetricKeyField(blank=True,null=True)classEncryptedModel(models.Model):pgp_sym_field=fields.TextPGPSymmetricKeyField(blank=True,null=True)fk_model=models.ForeignKey(EncryptedFKModel,blank=True,null=True,on_delete=models.CASCADE)
示例:
>>> import EncryptedModel
>>> my_model = EncryptedModel.objects.get().select_releated('fk_model')
>>> my_model.pgp_sym_field
'Value decrypted'
>>> my_model.fk_model.fk_pgp_sym_field
'Value decrypted'
哈希字段
为了过滤基于散列的值,我们需要比较散列。这是通过使用 查找的哈希值。
示例:
pip install django-pgcrypto-fields0
限制
.distinct('加密的字段名')
由于django orm中缺少功能,因此在加密字段上使用distinct()
。
不适用于django 2.0.x及更低版本。
django 2.1.x及更高版本上的正常DISTINCT工作:
pip install django-pgcrypto-fields1
django 2.0.x及更低版本的解决方案:
pip install django-pgcrypto-fields2
这是因为django将带注释的字段自动解密为f
字段,并且
字段用于distinct()
安全限制
参考PostgreSQL文档:
https://www.postgresql.org/docs/9.6/static/pgcrypto.html aen187024
所有pgcrypto函数都在数据库服务器内运行。也就是说 数据和密码以明文形式在pgcrypto和客户端应用程序之间移动。因此您必须:
- 连接L本地或使用SSL连接。
- 信任系统和数据库管理员。
如果不能,最好在客户端应用程序中进行加密。
该实现不抵抗侧信道攻击。例如,时间 pgcrypto解密函数完成不同密文所需的 给定的大小。
更改日志
2.5.1
- 修正了emailpgpppublickeyfield(77)定义中的回归
- 删除死代码(删除验证器和RemoveMaxLengthValidatorMixin)
- 更新了requirements\u dev.txt
2.5.0
- 为公钥和对称密钥添加了新的十进制字段(64)
- 为公钥和对称密钥(64)添加了新的floatfields
- 为公钥和对称密钥(64)添加了新的时间字段
- 增加了对基于数据库的不同密钥的支持(67)
2.4.0
- 添加了所有加密字段(包括FK表)的自动解密功能
- 删除了不再需要的django pgcrypto字段
aggregates
,pgpmanager
和pgpadmin
- 增加了对
get_或_create()
和update_或_create()
(27) 的支持
- 增加了对
get_by_natural_key()
(23) 的支持
- 添加了对
only()
和defer()
的支持,因为它们不受pgpmanager的支持
- 增加了对
distinct()
的支持(django 2.1+和2.0及更低版本的解决方案)- 将dev需求与setup.py需求分开
- 更新packaging/setup.py以包含详细说明
- 添加作者并更新投稿
- 更新travisci以使用xenial在矩阵中获得python 3.7
- 增加了对
2.3.1
- 添加了日期/日期时间字段的查找(59)
- 删除与django 1.8、1.9和1.10的兼容性(62)
- 改进了setup.py:
- 检查python 3.5+
- 更新的分类器
- 改进了
制作
文件以供发布使用捆绳
- 在"自述文件"中添加了额外的屏蔽
- 更新了travis配置以包括python 3.5和3.6
- 重构的查找和混合
2.3.0
- 释放无效,跳到2.3.1
2.2.0
- 将
.coveragerc
合并到setup.cfg
- 添加了
.gitignore
文件 - 更新过时的需求(最新版本的
flake8
和pycodesyle
彼此不兼容) - 更新了"自述文件",对字段进行了更好的解释
- 已实现DatePgpPublickeyField和DateTimePgpPublickeyField
2.1.1
- 增加了对django 2.x+的支持
- 更新了测试要求
- 使用Python3.6和其他环境更新了Travis配置
2.1.0
感谢@peterfarrell:
- 添加对
DatePgpsSymmetyKeyField
和DateTimePgpsSymmetyKeyField
的支持 包括对django表单字段序列化/反序列化的支持。 - 通过添加对对称密钥和公钥字段自动解密的支持 pgpmanager(以及通过pgpadmin在django管理中禁用它的支持)
2.0.0
- 删除
django 1.7的兼容性
- 为django 1.10添加兼容性
- 将django 1.9添加到travis矩阵中。
v1.0.1
- 从分布式软件包中排除测试应用程序。
v1.0.0
- 将包从
pgcrypto_fields
重命名为pgcrypto
v0.7.0
- make
get_placeholder
接受新参数编译器 - 将错误导入修复为
聚合
注意:这些更改已为django>;1.8.0完成。
v0.6.4
- 从电子邮件字段中删除
MaxLengthValidator
。
v0.6.3
- 避免在pgp字段上设置
max_length
。
v0.6.2
- 允许/检查
null
值:文本摘要字段
;texthmacfield
;电子邮件pgppublickeyfield
;integerPGPublicKeyField
;textpgppublickeyfield
;电子邮件pgpSymmetyKeyField
。integerpgpsymetrickeyfield
。textpgpsymmetykeyfield
v0.6.1
- 修复将负值发送到整数字段时的"转换"错误。
v0.6.0
- 添加
emailpgppublickeyfield
和emailpgpsymetykeyfield
v0.5.0
- 重命名以下字段:
pgppublickeyfield
到textpgpublickeyfield
;pgpsymetykeyfield
到textpgppsymetykeyfield
;摘要字段
到文本摘要字段
;hmacfield
到texthmacfield
- 添加新的整数字段:
integerPGPublicKeyField
;integerpgpsymetrickeyfield
v0.4.0
- 使访问解密值透明。修复字段有字符串时的错误
表示pgp和键控散列字段的
memoryView
。
V0.3.1
- 修正
encryptedproxyfield
以选择正确的项目。
v0.3.0
- 使用 字段的代理已解密
- 删除字段名称和原始值的描述符。
v0.2.0
- 为
digestfield
和hmacfield
添加基于哈希的查找
- 添加
digestfield
,hmacfield
,pgppublickeyaggregate
,pgpsymetykeyaggregate
v0.1.0
- 通过聚合类添加解密。
- 将数据插入数据库时添加加密。