簡體   English   中英

Django 加密 url 中的主鍵

[英]Django Encrypt primary key in a url

我環顧四周,但仍然不滿意如何安全地加密我的 django 應用程序 url 中的主 ID。

我的網址如下:

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

例如:

http://www.example.com/3/7/testing/

我想向用戶顯示上述網址,如下所示:

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

在我看來,我應該能夠從加密的密鑰中解碼出 primary1_id 和 primary2_id

請我需要一些有關如何以最佳方式處理它的指導

提前致謝!

我編寫了一個可以幫助您執行此操作的庫: django-encrypted-id 這是一個示例模型:

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..'

您可以進行反向查找:

In [5]: from encrypted_id import decode

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

如果您不能從 helper 基類繼承,沒問題,您可以使用 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-_]+.{0,2}"

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

"/<ekey:foo>/"

我建議在 UUID 上使用加密 ID, 因為 UUID 有應該考慮的重大問題(tldr:它們在磁盤和 RAM 上占用更多空間,並且索引比整數 ID 差),並且如果您的目標只是制作 URL不可猜測的加密 id 是一種優越的方法。

如果您對使用的加密感到好奇:我正在使用來自 pycrypto 庫的 AES,並且在 AES.CBC 模式下使用 SECRET_KEY 作為密碼 (SECRET_KEY[:24]) 和 IV (SECRET_KEY[-16:])。 一般來說,建議不要使用靜態 IV,但 CBC 可以抵消使用靜態 IV 的一些問題。 你問的靜態 IV 有什么問題:如果純文本“abc”和“abe”被加密,前兩個字節將是相同的。 現在這對我們來說不是一個嚴重的問題,因為我加密的純文本在有效載荷的開頭使用了 CRC32,所以即使你有 ids, 1, 11,攻擊者也不能說它們都以相同的第一個字符開頭.

該庫還支持由於某種原因必須循環 SECRET_KEY 的情況,因此使用舊 SECRET_KEY 加密的 URL 在更改后仍然可以解碼(只要您將舊版本存儲在 SECRET_KEYS 設置中)。 為了解密,庫會嘗試每個秘密密鑰,並比較數據的 CRC32 以確保知道(就像事情進入這樣的事情一樣),我們已經正確解密了。

請隨時在encrypted-id github repo 中提出問題,如果您遇到任何問題,我很樂意提供幫助。 該庫支持 python 2.7 和 3.5,以及 django 團隊支持的所有 django 版本。

$(function() { //on page load

    $( ".exampleclass" ).each(function( index ) { //replace each url
      var url = $(this).attr('href'); //get current url
      var encodedUrl = encodeURIComponent(url); //enconde url
      $(this).attr("href", encodedUrl); /replace
    });

});

結果:

http://10.91.161.54:8181/validate_/listActivi/314/

http://10.91.161.54:8181/validate_/%2Fvalidate_%2FlistActivi%2F314%2F%20

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM