跳转到主要内容

Django模型加密ID

项目描述

注意:从版本0.3.0开始生成的加密ID将与版本0.2.0生成的加密ID不同。但版本0.3.x将解密由版本0.2.0生成的ID。

注意:版本0.2.0与版本0.1.x不兼容。如果您已经在永久链接中使用ekey,则建议您不要升级到0.2.x。


考虑以下示例模型

from django.db import models

from encrypted_id.models import EncryptedIDModel


class Foo(EncryptedIDModel):
    text = models.TextField()

通过继承自EncryptedIDModel,您在模型实例上获得.ekey属性。它们将如下所示

In [1]: from tapp.models import Foo

In [2]: f = Foo.objects.create(text="asd")

In [3]: f.id
Out[3]: 1

In [4]: f.ekey
Out[4]: 'bxuZXwM4NdgGauVWR-ueUA'
You can do reverse lookup:

In [5]: from encrypted_id import decode

In [6]: decode(f.ekey)
Out[6]: 1

如果您不能从辅助基类继承,没问题,您可以直接使用encrypted_id包中的ekey()函数

In [7]: from encrypted_id import ekey

In [8]: from django.contrib.auth.models import User

In [9]: ekey(User.objects.get(pk=1))
Out[9]: 'bxuZXwM4NdgGauVWR-ueUA'

要进行反向查找,您有两个辅助工具可供选择。第一个由EncryptedIDManager提供,如果您从EncryptedIDModel继承,并且没有重写.objects

In [10]: Foo.objects.get_by_ekey(f.ekey)
Out[10]: <Foo: Foo object>

但有时您可能更喜欢以下形式

In [11]: Foo.objects.get_by_ekey_or_404(f.ekey)
Out[11]: <Foo: Foo object>

它们的工作方式相同,但与抛出DoesNotExist不同,它抛出Http404,因此可以在视图中使用。

如果您的管理器不是继承自EncryptedIDManager,您可以使用

In [12]: e = ekey(User.objects.first())

In [13]: e
Out[13]: 'bxuZXwM4NdgGauVWR-ueUA'

In [14]: get_object_or_404(User, e)
Out[14]: <User: amitu>

《encrypted_id.get_object_or_404》以及《EncryptedIDManager.get_by_ekey》和《EncryptedIDManager.get_by_ekey_or_404》函数接受额外的关键字参数,您可以使用这些参数进行过滤。

如果您对匹配生成的ID所使用的正则表达式感兴趣,那么它是这样的

"[0-9a-zA-Z-_]+"

如果您使用smarturls,您可以使用以下URL模式

"/<ekey:foo>/"

我推荐使用加密ID而不是UUID,因为UUID存在一些重大问题(简而言之:它们在磁盘和RAM中占用更多空间,并且索引性能不如整数ID),而如果您的目标是使URL不可预测,那么加密ID是更优的方法。

如果您对所使用的加密方法感兴趣:我使用的是来自《pycrypto》库的《AES》,并使用《SECRET_KEY》作为密码(取《SECRET_KEY[:32]》)和《IV》(《SECRET_KEY》的哈希值的第一个16个字符加上一个sub_key),在《AES.CBC》模式下。这个sub_key来自模型的《Meta》属性《ek_key》,如果没有设置《ek_key》,则简单地使用《db_table》。

通常建议不要有静态的《IV》,但《CBC》模式解决了一些静态IV的问题。您问静态IV有什么问题:如果明文“abc”和“abe”被加密,前两个字节将相同。现在这对我们来说并不构成严重问题,因为我所加密的明文在有效载荷的开始处使用了《CRC32》,因此即使你有ID,1,11,攻击者也不能说它们以相同的首字母开头。

该库还支持您因为某些原因需要循环使用《SECRET_KEY》的情况,因此使用旧的《SECRET_KEY》加密的URL在更改后仍然可以解码(只要您在《SECRET_KEYS》设置中存储旧版本)。为了解密,库尝试每个秘密密钥,并比较数据的《CRC32》值,以确保(在这个问题上尽可能确定)我们已经正确地解密。

如果您遇到任何问题,请随时在此处提出,我会很高兴帮助您。该库支持python 2.7和3.5,以及django团队支持的django所有版本。

项目详情


下载文件

下载适用于您的平台文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分发

django-encrypted-id-0.3.2.tar.bz2 (6.1 kB 查看哈希值)

上传时间

构建分发

django_encrypted_id-0.3.2-py2.py3-none-any.whl (5.7 kB 查看哈希值)

上传时间 Python 2 Python 3

由...