Coder Social home page Coder Social logo

django-encrypted-id's Introduction

I have written a library that helps you do this: django-encrypted-id. Here is an example model:

from django.db import models

from encrypted_id.models import EncryptedIDModel

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

By inheriting from EncryptedIDModel, you get .ekey as a property on your model instances. This is how they will look like:

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..' You can do reverse lookup:

In [5]: from encrypted_id import decode

In [6]: decode(f.ekey) Out[6]: 1 If you can not inherit from the helper base class, no problem, you can just use the ekey() function from encrypted_id package:

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..' To do the reverse lookup, you have two helpers available. First is provided by EncryptedIDManager, which is used by default if you inherit from EncryptedIDModel, and have not overwritten the .objects:

In [10]: Foo.objects.get_by_ekey(f.ekey) Out[10]: <Foo: Foo object> But sometimes you will prefer the form:

In [11]: Foo.objects.get_by_ekey_or_404(f.ekey) Out[11]: <Foo: Foo object> Which works the same, but instead of raising DoesNotExist, it raises Http404, so it can be used in views.

You your manager is not inheriting from EncryptedIDManager, you can use:

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, as well as EncryptedIDManager.get_by_ekey and EncryptedIDManager.get_by_ekey_or_404 take extra keyword argument, that can be used to filter if you want.

If you are curios, the regex used to match the generated ids is:

"[0-9a-zA-Z-_]+.{0,2}" If you are using smarturls, you can use URL pattern like:

"/<ekey:foo>/" I recommend this usage of encrypted-id over UUID, as UUIDs have significant issues that should be considered (tldr: they take more space on disk and RAM, and have inferior indexing than integer ids), and if your goal is simply to make URLs non guessable, encrypted id is a superior approach.

If you are curious about the encryption used: I am using AES, from pycrypto library, and am using SECRET_KEY for password (SECRET_KEY[:24]) and IV (SECRET_KEY[-16:]), in the AES.CBC mode. In general it is recommended not to have static IV, but CBC offsets some of the problems with having static IV. What is the the issue with static IV you ask: if plain text "abc" and "abe" are encrypted, the first two bytes would be same. Now this does not present a serious problem for us, as the plain text that I am encrypting uses CRC32 in the beginning of payload, so even if you have ids, 1, 11, an attacker can not say they both start with same first character.

The library also supports the scenario that you have to cycle SECRET_KEY due to some reason, so URLs encrypted with older SECRET_KEY can still be decoded after you have changed it (as long as you store old versions in SECRET_KEYS setting). In order to decrypt the library tries each secret key, and compares the CRC32 of data to know for sure (as sure as things get in such things), that we have decrypted properly.

Do feel free to raise an issue in encrypted-id github repo, if you face any issues, I would be happy to help. The library supports both python 2.7 and 3.5, as well as it all versions of django that django team supports.

django-encrypted-id's People

Contributors

bahiamartins avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.