Problem RSA cryptographie in python [django]
I've following code in python, django, to share symetric cryptographie for encrypt/decrypt files, using RSA cryptographie, i can allready create RSA keys and store them in the member model, also I'm able to create the securit_key_relations, but then the private_key_relation in member model is empty, I tried everything and don't know why.
models.py
class Member(models.Model):
private_key=models.TextField(blank=True, null=True)
public_key=models.TextField(blank=True, null=True)
private_key_relation=models.TextField(blank=True, null=True)
dc_verification=models.CharField(max_length=50, blank=True, null=True)
id=models.AutoField(primary_key=True)
permission=models.TextField(default="")
mma_classification=models.IntegerField(default=1)
firstname=models.CharField(max_length=30, null=True)
lastname=models.CharField(max_length=30, null=True)
username=models.CharField(max_length=30, null=True, unique=True)
password=models.CharField(max_length=1000, null=True)
agentnr=models.CharField(max_length=11, null=True, unique=True)
bezlogged=models.CharField(max_length=20, null=True)
frei=models.BooleanField(default='FALSE')
email=models.EmailField(max_length=50)
code=models.CharField(max_length=50, null=True, unique=True)
verify=models.BooleanField(default=False)
ort=models.CharField(max_length=50, null=True)
bereitschaftsort=models.CharField(max_length=50, null=True)
land=models.CharField(max_length=4, default='ENG')
phonenumber=models.CharField(max_length=20, default='0000000000')
kategorie=models.CharField(max_length=9, default='agent')
benachrichtigt=models.BooleanField(default='FALSE')
abteilung=models.CharField(max_length=30, null=True)
einsatztag=models.CharField(max_length=30, default='agent')
status=models.CharField(max_length=1, default='5')
api_user=models.BooleanField(default='False')
dc_tag=models.CharField(max_length=100, null=True)
support=models.CharField(max_length=100, default="no_support")
prioritaet=models.CharField(max_length=1, default="1")
pefw=models.BooleanField(default=False)
device_code=models.TextField(default="X", max_length=1000)
device_id=models.CharField(max_length=100, default='X')
def __str__(self):
return self.firstname + " " + self.lastname
class security_key_rel(models.Model):
id=models.AutoField(primary_key=True)
gmid=models.TextField(blank=True, null=True)
key=models.TextField(blank=True, null=True)
purpose=models.TextField(blank=True, null=True)
`
views.py
`def byte_to_string(byte_obj):
return byte_obj.decode('utf-8')
def string_to_byte(string_obj):
return string_obj.encode()
def encrypt_file(filename, key):
key = string_to_byte(key)
f = Fernet(key)
with open(filename, 'rb') as file:
file_data = file.read()
encrypted_data = f.encrypt(file_data)
os.remove(filename)
with open(filename, 'wb') as file:
file.write(encrypted_data)
def decrypt_file(filename, key):
key = string_to_byte(key)
f = Fernet(key)
with open(filename, 'rb') as file:
encrypted_data = file.read()
decrypted_data = f.decrypt(encrypted_data)
os.remove(filename)
with open(filename, 'wb') as file:
file.write(decrypted_data)
def generate_RSA_key():
key = RSA.generate(2048)
private_key = key.export_key()
public_key = key.publickey().export_key()
return(private_key, public_key)
def encrypt_string_rsa(data, public_key):
public_key = RSA.import_key(public_key)
public_key = PKCS1_OAEP.new(public_key)
ciphertext = public_key.encrypt(data)
return base64.b64encode(ciphertext)
def decrypt_string_rsa(ciphertext, private_key):
private_key = RSA.import_key(private_key)
private_key = PKCS1_OAEP.new(private_key)
ciphertext = base64.b64decode(ciphertext)
data = private_key.decrypt(ciphertext)
return (data)
def generate_key_from_seed(seed):
"""Generates a key from a seed using PBKDF2."""
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=seed.encode(),
iterations=390000,
)
derived_key = kdf.derive("f0fc0cf3f8msheba5a7453de9c76p143857jsn01955c3102f7".encode())
encoded_key = urlsafe_b64encode(derived_key)
return byte_to_string(encoded_key)
def encrypt_file(filename, key):
key = string_to_byte(key)
f = Fernet(key)
with open(filename, 'rb') as file:
file_data = file.read()
encrypted_data = f.encrypt(file_data)
os.remove(filename)
with open(filename, 'wb') as file:
file.write(encrypted_data)
return 200
def decrypt_file(filename, key):
key = string_to_byte(key)
f = Fernet(key)
with open(filename, 'rb') as file:
encrypted_data = file.read()
decrypted_data = f.decrypt(encrypted_data)
os.remove(filename)
with open(filename, 'wb') as file:
file.write(decrypted_data)
return 200
def encrypt_string(string, key):
key = string_to_byte(key)
"""Encrypts a string using Fernet."""
fernet = Fernet(key)
return byte_to_string(fernet.encrypt(string))
def decrypt_string(ciphertext, key):
key = string_to_byte(key)
"""Decrypts a string using Fernet."""
fernet = Fernet(key)
return byte_to_string(fernet.decrypt(ciphertext))
def generate_key():
return byte_to_string(Fernet.generate_key())
#register
def intialisise_RSA(id, key): #key = 3th pwd hash
key = string_to_byte(key)
member = Member.objects.get(id=id)
private_key, public_key = generate_RSA_key()
member.public_key = byte_to_string(public_key)
member.private_key = (encrypt_string(private_key, (generate_key_from_seed(byte_to_string(key)))))
member.save()
return 200
def new_key_relation(member_id, user_id, key, description): #key = byte format
member = Member.objects.get(id=member_id)
if not member.private_key:
intialisise_RSA(member_id, key)
key = string_to_byte(key)
member = Member.objects.get(id=member_id)
user = Member.objects.get(id=user_id)
ciphertext = encrypt_string_rsa(key, string_to_byte(member.public_key))
data = json.loads(member.private_key_relation)
data[f"{description}"] = byte_to_string(ciphertext)
member.private_key_relation = str(json.dumps(data))
member.save()
return 200
def delete_key_relation(member_id, user_id, description):
member = Member.objects.get(id=member_id)
user = Member.objects.get(id=user_id)
data = json.loads(member.private_key_relation)
del data[description]
member.private_key_relation = str(json.dumps(data))
member.save()
return 200
def get_key(member_id, description, key):
key = string_to_byte(key)
member = Member.objects.get(id=member_id)
data = json.loads(member.private_key_relation)
encrypted_key = (data[description])
key = decrypt_string(string_to_byte(encrypted_key), string_to_byte(generate_key_from_seed(key)))
return key
def create_security_key_relation(member_id, description, key):
member = Member.objects.get(id=member_id)
member.device_id = "test-2"
member.save()
if not member.private_key:
intialisise_RSA(member_id, key)
member = Member.objects.get(id=member_id)
member = Member.objects.get(id=member_id)
key = string_to_byte(key)
if not security_key_rel.objects.filter(purpose=description).exists():
member = Member.objects.get(id=member_id)
member.device_id = "test-1"
member.save()
key1 = string_to_byte(generate_key())
key2 = string_to_byte(generate_key())
skr = security_key_rel(purpose=description, key=encrypt_string(key1, byte_to_string(key2)))
skr.save()
#development 24_02_2024 <error>
member = Member.objects.get(id=member_id)
member.lastname = "test0"
member.save()
data = json.loads(member.private_key_relation)
member = Member.objects.get(id=member_id)
member.lastname = "test1"
member.save()
ciphertext = encrypt_string_rsa(key2, string_to_byte(member.public_key))
member = Member.objects.get(id=member_id)
member.lastname = "test2"
member.save()
data[f"{description}"] = byte_to_string(ciphertext)
member = Member.objects.get(id=member_id)
member.lastname = "test3"
member.save()
member.private_key_relation = str(json.dumps(data))
member.save()
else:
skr = security_key_rel.objects.get(purpose=description)
data = json.loads(member.private_key_relation)
member
key2 = decrypt_string_rsa(((data[description])), (decrypt_string(string_to_byte(member.private_key), (generate_key_from_seed(key)))))
key1 = string_to_byte(decrypt_string(string_to_byte(skr.key), byte_to_string(key2)))
return key1, key2
#description = [psc ohne 500.xx aufsteigend]
#register > psc & update psc edit key relations
def add_member_from_security_key_relation(member_ids, description, key, member_id, add): #key = 3th pwd hash; member_ids = [1, 2, 4, 6]
member = Member.objects.get(id=member_id)
if not member.private_key:
intialisise_RSA(member_id, key)
member = Member.objects.get(id=member_id)
key = string_to_byte(key)
if add != "":
des1 = description
description = add
ciphertext = json.loads(member.private_key_relation)[description]
ciphertext = string_to_byte(ciphertext)
skr_key = string_to_byte(decrypt_string_rsa(ciphertext, string_to_byte(decrypt_string(string_to_byte(member.private_key), string_to_byte(generate_key_from_seed(key))))))
for id in member_ids:
if add != "":
description = des1
if not Member.objects.get(id=id).public_key:
intialisise_RSA(id, byte_to_string(key))
mem = Member.objects.get(id=id)
data = json.loads(mem.private_key_relation)
if not data[description]:
ciphertext = encrypt_string_rsa(skr_key, string_to_byte(mem.public_key))
data[f"{description}"] = byte_to_string(ciphertext)
mem.private_key_relation = str(json.dumps(data))
mem.save()
return 200
def format_psc(data): # = [30,500.40,21,1]
return sorted([int(i) for i in data if isinstance(i, int)]) # [1,21,30,40]
def generate_combinations_formatted(data):
data = format_psc(data)
from itertools import combinations
return [list(combo) for r in range(1, len(data) + 1) for combo in combinations(data, r)]
mmaedit(...): [...]
member = Member.objects.get(username=username)
m = Member.objects.get(agentnr=member_agentnr)
x = ['207', '120.19']
for i in (str(request.POST['permissions']).split(',')):
x.append(i)
if validate_permission(username, password, x):
#development 24_02_2024 <start>
data = []
for i in request.POST['permissions'].split(','):
try:
data.append(int(i))
except:
pass
combinations_to_add = generate_combinations_formatted(data)
m.private_key_relation = "{}"
m.save()
for l in combinations_to_add:
create_security_key_relation(member.id, f"{l}", key)
#add_member_from_security_key_relation([m.id], f"{l}", key, member.id, "")
#development 24_02_2024 <ende>
m.permission = request.POST['permissions']
For debugging reasons I implemented some code to save text in the member.device_id, in create_security_key_relations the problems begann. test-2 is saved correctly, but then nothing more. Also i got no error and the permissions are saved very well, according to mmaedit()
I only wanna create RSA and then create for every possible permission combination an own security_key
_relation object and share the key via RSA in JSON format in TextField() [because of Django 3.0.1] in member.private_key_relation.