Django加密u中的主键

2024-10-04 11:29:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我看了很多遍,但仍然不太熟悉如何在django应用程序的url中安全地加密主id。在

我的网址如下:

http://www.example.com/primary1_id/primary2_id/testing/

例如:

^{pr2}$

我想向用户显示上述url,如下所示:

http://www.example.com/623477897ghfjs23879/7829yfgweh/testing/ #encrypted key instead of primary id

在我看来,我应该能够从加密密钥中解码出primary1_id和primary2_id

我需要一些最好的方法来处理

提前谢谢!在


Tags: django用户comid应用程序httpurlexample
1条回答
网友
1楼 · 发布于 2024-10-04 11:29:22

{我帮你写了一个图书馆。下面是一个示例模型:

from django.db import models

from encrypted_id.models import EncryptedIDModel


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

通过从EncryptedModel继承,可以将.ekey作为模型实例的属性。这就是它们的样子:

^{pr2}$

您可以执行反向查找:

In [5]: from encrypted_id import decode

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

如果不能从helper基类继承,没问题,可以从加密的_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提供,如果从EncryptedModel继承,并且没有覆盖.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>

它的工作原理是一样的,但是它没有提升doesnotextist,而是提升了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>

加密_id.get_object_或_404,以及EncryptedIDManager.get_by_ekey以及EncryptedIDManager.get_按_ekey_或_404使用额外的关键字参数,如果需要,可以用来过滤。在

如果您是古董,则用于匹配生成的ID的regex是:

"[0-9a-zA-Z-_]+.{0,2}"

如果您使用的是smarturls,则可以使用以下URL模式:

"/<ekey:foo>/"

我建议在UUID上使用加密id,as UUIDs have significant issues that should be considered(tldr:它们占用磁盘和RAM上更多的空间,并且索引比整数id差),如果您的目标只是使url不可猜测,那么加密id是一种更好的方法。在

如果您对所使用的加密很好奇:我使用的是pycrypto库中的AES,并且在AES.CBC公司模式。一般情况下,建议不要使用静态IV,但CBC抵消了静态IV的一些问题。您会问静态IV的问题是什么:如果纯文本“abc”和“abe”是加密的,则前两个字节将是相同的。现在这对我们来说并不是一个严重的问题,因为我加密的纯文本在有效负载的开头使用CRC32,所以即使您有id,1,11,攻击者也不能说它们都以相同的第一个字符开头。在

该库还支持由于某些原因必须循环密钥的情况,因此使用旧密钥加密的URL在更改后仍然可以解码(只要将旧版本存储在SECRET_KEYS设置中)。为了解密,库会尝试每个密钥,并比较数据的CRC32,以确定(正如在这样的事情中得到的一样),我们已经正确地解密了。在

请随时在encrypted-id github repo中提出问题,如果您遇到任何问题,我很乐意为您提供帮助。该库支持python2.7和3.5,以及django团队支持的所有django版本。在

相关问题 更多 >