2010-02-18 5 views
5

J'ai besoin d'organiser une sorte d'encodage pour générer des liens spécifiques à l'utilisateur. Les utilisateurs vont cliquer sur ce lien et à un autre point de vue, le lien associé à la chaîne cryptée sera décrypté et le résultat sera retourné. Pour cela, j'ai besoin d'une sorte de fonction de chiffrement qui consomme un nombre (ou une chaîne) qui est la clé primaire de mon élément sélectionné lié au compte de l'utilisateur, consommant également une sorte de graine et générant un code de chiffrement cela sera décrypté à une autre page.django, python et cryptage de liens

donc quelque chose comme ça

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 

Je veux que mon « semence » pour être une sorte de variable primaire (pas une classe) à cet effet (à savoir un nombre ou une chaîne).

Comment puis-je y parvenir sous python et django?

+0

Pourquoi ne pas simplement utiliser le' session' pour cette ? – voyager

+0

Je pense que vous voulez dire vérifier utilisateur auth, oui je vais en effet les utiliser mais aussi je ne veux pas non plus afficher les articles aux utilisateurs et les crypter à la place – Hellnar

Répondre

8

Il n'y a pas d'algorithmes de cryptage, en soi, intégrés à Python. Cependant, vous voudrez peut-être regarder le Python Cryptography Toolkit (PyCrypt). Je l'ai seulement bricolé, mais il est référencé dans la documentation de Python sur cryptographic services. Voici un exemple de la façon dont vous pouvez chiffrer une chaîne avec AES à l'aide 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) 

Vous pouvez ensuite faire cette partie de votre URL, peut-être dans le cadre d'une requête GET.

Pour déchiffrer, il suffit d'inverser le processus; en supposant que encryption_obj est créé comme ci-dessus, et que vous avez récupéré la partie pertinente de l'URL, ce serait le faire:

from urllib import unquote 

# We've already created encryption_object as shown above 

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

Vous pouvez également envisager une approche différente: une méthode simple serait de hachage primaire clé (avec un sel, si vous le souhaitez) et stocker le hachage et pk dans votre base de données. Donner à l'utilisateur le hachage dans le cadre de son lien, et quand ils reviennent et présentent le hachage, recherchez le pk correspondant et renvoyez l'objet approprié. (. Si vous voulez aller dans cette voie, consultez la bibliothèque intégrée hashlib)

À titre d'exemple, vous auriez quelque chose comme ça défini dans 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() 

Et vous » d générer le hachage dans une vue en utilisant quelque chose comme ce qui suit:

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

Notez que vous auriez à citer cette version ainsi; Si vous préférez, vous pouvez utiliser hexdigest() au lieu de digest (vous n'aurez pas à citer la chaîne résultante), mais vous devrez ajuster la longueur du champ à 64.

+0

merci peppergrower! – Hellnar

+0

J'ai essayé votre méthode et ajouter la chaîne entre guillemets à url, mais le django a échoué.Les détails peuvent être vus à ce fil: http://stackoverflow.com/questions/8685139/django-cant-haut-quoted-characters-in-urls –

0

Django a des fonctionnalités pour cela maintenant. Voir https://docs.djangoproject.com/en/dev/topics/signing/

citant cette page:

« Django fournit à la fois une API de bas niveau pour les valeurs de signature et une API de haut niveau pour le réglage et la lecture des cookies signés, l'une des utilisations les plus courantes de signature dans les applications Web .

Vous pouvez également trouver la signature utile pour ce qui suit:

  • Génération URL « récupérer mon compte » pour envoyer aux utilisateurs qui ont perdu leur mot de passe.
  • Garantir que les données stockées dans les champs masqués n'ont pas été altérées.
  • Génération URL secret partagé pour permettre un accès temporaire à une ressource protégée, pour -. Par exemple un fichier téléchargeable qu'un utilisateur a payé pour »