- Author:
- equanimity
- Posted:
- February 19, 2009
- Language:
- Python
- Version:
- 1.0
- Score:
- 4 (after 4 ratings)
I've often found myself wanting to store passwords for other web services (e.g. maillist managers, IMAP accounts, IM accounts etc) for use by a web application, but have not wanted to hard-code them in settings.py
or store them as plaintext in the database.
This uses the pycrypto library to encrypt each bit of information using the concatenation of a salt value and the SECRET_KEY value from your settings.py
, hopefully leading to a bit more security and flexibility.
You'll probably want to add some views to let people edit these things as I can't find a way to make the admin interface play nicely with it.
Example usage:
In [1]: p = Password(
name='IMAP account', slug='imap',
username='example', password='password',
host='imap.gmail.com'
)
In [2]: p.host
Out[2]: 'imap.gmail.com'
In [3]: p.e_host
Out[3]: '6wdyMDKYy8c=$YXw6t/Q9wI[...]'
In [4]: p.save()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | from os import urandom
from base64 import b64encode, b64decode
from django.db import models
from Crypto.Cipher import ARC4
def get_value(name):
def f(self):
return Password.decrypt(getattr(self, 'e_%s'%name))
return f
def set_value(name):
def f(self, value):
setattr(self, 'e_%s'%name, Password.encrypt(value))
return f
class Password(models.Model):
SALT_SIZE = 8
name = models.CharField(max_length=128)
slug = models.SlugField()
e_username = models.TextField(blank=True)
e_password = models.TextField(blank=True)
e_host = models.TextField(blank=True)
e_resource = models.TextField(blank=True)
@staticmethod
def encrypt(plaintext):
salt = urandom(Password.SALT_SIZE)
arc4 = ARC4.new(salt + settings.SECRET_KEY)
plaintext = "%3d%s%s" % (len(plaintext), plaintext, urandom(256-len(plaintext)))
return "%s$%s" % (b64encode(salt), b64encode(arc4.encrypt(plaintext)))
@staticmethod
def decrypt(ciphertext):
salt, ciphertext = map(b64decode, ciphertext.split('$'))
arc4 = ARC4.new(salt + settings.SECRET_KEY)
plaintext = arc4.decrypt(ciphertext)
return plaintext[3:3+int(plaintext[:3].strip())]
def encrypted_property(name):
return property(get_value(name), set_value(name))
username = encrypted_property('username')
password = encrypted_property('password')
host = encrypted_property('host')
resource = encrypted_property('resource')
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
You can adapt it to admin with something like this:
In admin.py file: class MyClass(BLA,BLA): resource_class = LockerModelResource
With this, you can now add a encrypted password in admin.
#
Please login first before commenting.