2010-02-18 25 views
5

我需要安排某種形式的用於生成用戶特定鏈接的加密。用戶將點擊此鏈接,並在其他視圖中,與加密字符串相關的鏈接將被解密並返回結果。django,python和鏈接加密

爲此,我需要某種類型的加密函數,它使用一個數字(或字符串),這是我選擇的與用戶帳戶綁定的項目的主鍵,也消耗某種種子並生成加密代碼這將在其他頁面解密。

所以像這樣

my_items_pk = 36 #primary key of an item 
seed = "rsdjk324j23423j4j2" #some string for crypting 
encrypted_string = encrypt(my_items_pk,seed) 
#generates some crypted string such as "dsaj2j213jasas452k41k" 
and at another page: 
decrypt_input = encrypt(decypt,seed) 
print decrypt_input 
#gives 36 

我希望我的「種子」是某種主要變量(不是一些類)用於此目的(即某些數字或字符串)。

如何在python和django下實現這個功能?

+0

你爲什麼不只是使用'session'此? – voyager 2010-02-18 18:43:01

+0

我認爲你的意思是檢查用戶身份驗證,是的,我確實會使用他們,但我也不想顯示項目PK給用戶,而是隱藏他們。 – Hellnar 2010-02-18 18:48:59

回答

8

本身沒有內置到Python的加密算法。但是,您可能需要查看Python Cryptography Toolkit(PyCrypt)。我只修改了它,但它在Python的文檔cryptographic services中被引用。這裏是你怎麼可以加密使用AES PyCrypt一個字符串的例子:

from Crypto.Cipher import AES 
from urllib import quote 

# Note that for AES the key length must be either 16, 24, or 32 bytes 
encryption_obj = AES.new('abcdefghijklmnop') 
plain = "Testing" 

# The plaintext must be a multiple of 16 bytes (for AES), so here we pad it 
# with spaces if necessary. 
mismatch = len(plain) % 16 
if mismatch != 0: 
    padding = (16 - mismatch) * ' ' 
    plain += padding 

ciph = encryption_obj.encrypt(plain) 

# Finally, to make the encrypted string safe to use in a URL we quote it 
quoted_ciph = quote(ciph) 

你會那麼做你的URL的這一部分,也許作爲一個GET請求的一部分。

解密,只是扭轉過程;假設encryption_obj如上創建的,你已經檢索到的URL的相關部分,這將做到這一點:

from urllib import unquote 

# We've already created encryption_object as shown above 

ciph = unquote(quoted_ciph) 
plain = encryption_obj.decrypt(ciph) 

您也可以考慮不同的方法:一個簡單的方法是哈希主鍵(如果你願意,可以用鹽)並將散列和pk存儲在數據庫中。給用戶散列作爲鏈接​​的一部分,當他們返回並呈現散列時,查找相應的pk並返回適當的對象。 (如果你想要走這條路線,檢查出的內置庫hashlib

舉個例子,你有這樣的事情在models.py定義:

class Pk_lookup(models.Model): 
    # since we're using sha256, set the max_length of this field to 32 
    hashed_pk = models.CharField(primary_key=True, max_length=32) 
    key = models.IntegerField() 

你」 d使用類似如下生成視圖中的散列:

import hashlib 
import Pk_lookup 

hash = hashlib.sha256() 
hash.update(str(pk)) # pk has been defined previously 
pk_digest = hash.digest() 

lookup = Pk_lookup(hashed_pk=pk_digest,key=pk) 
lookup.save() 

請注意,你必須引用此版本爲好;如果你願意,你可以使用hexdigest()而不是digest(你不必引用結果字符串),但你必須調整字段的長度爲64.

+0

謝謝peppergrower! – Hellnar 2010-02-20 13:49:35

+0

我試過你的方法,並添加引用的字符串到url。但Django失敗。詳細信息可以在此線程看到:http://stackoverflow.com/questions/8685139/django-cant-have-quoted-characters-in-urls – 2011-12-30 23:50:05

0

Django現在有這個功能。見https://docs.djangoproject.com/en/dev/topics/signing/

引用該頁面:

「Django提供了既爲簽名值,低級別的API和用於設置和讀取簽署餅乾,簽約的Web應用程序中最常見的用途之一的高級API 。

您還可以找到以下籤署有用:

  • 生成「恢復我的帳戶」的網址發送給誰失去了他們的密碼的用戶。
  • 確保存儲在隱藏表單域中的數據沒有被篡改。
  • 生成一次性祕密網址,允許臨時訪問受保護的資源,爲 - 例如用戶已支付了下載文件」