Model to store password per project in django
import base64
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto import Random
from django.db import models
from django.conf import settings
def encrypt(key, source, encode=True):
key = SHA256.new(key).digest()
IV = Random.new().read(AES.block_size)
encryptor = AES.new(key, AES.MODE_CBC, IV)
padding = AES.block_size - len(source) % AES.block_size
source += bytes([padding]) * padding
data = IV + encryptor.encrypt(source)
return base64.b64encode(data).decode("utf-8") if encode else data
def decrypt(key, source, decode=True):
if decode:
source = base64.b64decode(source.encode("utf-8"))
key = SHA256.new(key).digest()
IV = source[:AES.block_size]
decryptor = AES.new(key, AES.MODE_CBC, IV)
data = decryptor.decrypt(source[AES.block_size:])
padding = data[-1]
if data[-padding:] != bytes([padding]) * padding:
raise ValueError("Invalid padding...")
return data[:-padding] # remove the padding
class Timestamped(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class AccountType(Timestamped):
name = models.CharField(max_length=100)
class Meta:
default_related_name = 'accounttypes'
verbose_name = 'account type'
verbose_name_plural = 'account types'
def __str__(self):
return self.name
class Project(Timestamped):
name = models.CharField(max_length=100)
class Meta:
default_related_name = 'projects'
verbose_name = 'project'
verbose_name_plural = 'projects'
def __str__(self):
return self.name
class Password(Timestamped):
account_type = models.ForeignKey(AccountType, on_delete=models.CASCADE)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
username = models.CharField(max_length=100)
password = models.CharField(max_length=255)
comments = models.TextField(blank=True)
url = models.URLField(blank=True)
class Meta:
default_related_name = 'passwords'
verbose_name = 'password'
verbose_name_plural = 'passwords'
def __str__(self):
return self.username
def save(self, *args, **kwargs):
encrypted = encrypt(bytes(settings.SECRET_KEY, 'utf-8'), bytes(self.password, 'utf-8'))
self.password = encrypted
decrypted = decrypt(bytes(settings.SECRET_KEY, 'utf-8'), encrypted)
print(encrypted)
print(decrypted)
super().save(*args, **kwargs)