2010-02-18 13 views
5

Ich muss eine Art von Verschlüsselung für die Erstellung benutzerspezifische Links arrangieren. Benutzer klicken auf diesen Link und bei einer anderen Ansicht wird der zugehörige Link mit der verschlüsselten Zeichenfolge entschlüsselt und das Ergebnis wird zurückgegeben.Django, Python und Link-Verschlüsselung

Dafür brauche ich eine Art von Verschlüsselungsfunktion, die eine Zahl (oder eine Zeichenfolge) verbraucht, die der Primärschlüssel meines ausgewählten Elements ist, der an das Benutzerkonto gebunden ist und auch eine Art Seed und die Generierung von Verschlüsselungscode verbraucht Das wird auf einer anderen Seite entschlüsselt.

so etwas wie dieses

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 

Ich möchte, dass meine „Samen“ eine Art primäre Variable sein (nicht einige Klasse) für diesen Zweck (dh eine Zahl oder eine Zeichenkette).

Wie kann ich dies unter Python und Django erreichen?

+0

Warum Sie nicht nur verwenden, um den' session' für diesen ? – voyager

+0

Ich denke, du meinst Benutzerauth prüfen, ja ich werde sie in der Tat Benutzer aber auch ich will auch nicht Artikel pks zu den Benutzern zeigen und stattdessen crypt sie. – Hellnar

Antwort

8

In Python sind keine per se integrierten Verschlüsselungsalgorithmen integriert. Vielleicht möchten Sie jedoch die Python Cryptography Toolkit (PyCrypt) betrachten. Ich habe nur daran herumgebastelt, aber es ist in Pythons Dokumentation auf cryptographic services verwiesen. Hier ist ein Beispiel dafür, wie man einen String mit AES PyCrypt verschlüsseln könnte:

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) 

Sie würden dann diesen Teil Ihrer URL machen, vielleicht als Teil einer GET-Anfrage.

Um zu entschlüsseln, einfach den Prozess umkehren; unter der Annahme, dass encryption_obj wie oben erstellt wird, und dass Sie den entsprechenden Teil der URL abgerufen hat, dies würde es tun:

from urllib import unquote 

# We've already created encryption_object as shown above 

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

Sie könnten auch einen anderen Ansatz betrachten: eine einfache Methode wäre die primäre Hash Schlüssel (mit einem Salz, wenn Sie wünschen) und speichern Sie die Hash-und PK in Ihrer Datenbank. Geben Sie dem Benutzer den Hash als Teil seiner Verknüpfung, und wenn sie zurückkommen und den Hash darstellen, suchen Sie den entsprechenden PK und geben Sie das entsprechende Objekt zurück. (. Wenn Sie diesen Weg gehen wollen, besuchen Sie das integrierte Bibliothek hashlib)

Als Beispiel, würden Sie so etwas wie dies in models.py definiert haben:

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() 

Und Sie‘ d erzeugen, um den Hash in einer Ansicht mit so etwas wie folgt aus:

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() 

Beachten Sie, dass Sie würde diese Version als auch zu zitieren; Wenn Sie möchten, können Sie hexdigest() anstelle von digest verwenden (Sie müssten die resultierende Zeichenfolge nicht zitieren), aber Sie müssen die Länge des Feldes auf 64 anpassen.

+0

danke peppergrower! – Hellnar

+0

Ich habe versucht, Ihre Methode und fügen Sie die Zeichenfolge in Anführungszeichen zu url. Aber django ist fehlgeschlagen. Die Details können in diesem Thread gesehen werden: http://stackoverflow.com/questions/8685139/django-cant-have-quoted-characters-in-urls –

0

Django verfügt jetzt über Funktionen. Siehe https://docs.djangoproject.com/en/dev/topics/signing/

Zitiert die Seite:

„Django bietet sowohl eine Low-Level-API für die Signierung Werte und eine High-Level-API für das Setzen und Lesen unterzeichnet Cookies, eine der häufigsten Anwendungen der Unterzeichnung in Webanwendungen .

Sie können auch die Unterzeichnung, die für die folgenden finden:

  • Generieren von URLs „mein Konto wiederherstellen“ für die Benutzer zu senden, um die ihr Passwort verloren haben.
  • Sicherstellen, dass in versteckten Formularfeldern gespeicherte Daten nicht manipuliert wurden.
  • Generieren einmalige geheime URLs zu ermöglichen temporären Zugriff auf eine geschützte Ressource, für -. Beispiel eine herunterladbare Datei, die ein Benutzer bezahlt hat“