简体   繁体   English

django 文件存储前加密

[英]django encrypt files before storage

So I want to encrypt files before storage in django and decrypt them upon retrieval.所以我想在存储在 django 之前加密文件并在检索时解密它们。

I am using a custom storage class for the same and the cryptography module.我正在使用自定义存储 class 和密码模块。

import hashlib
import os
import uuid

import django.core.files.storage as storage
from cryptography.fernet import Fernet
from django.conf import settings
from django.core.files import File


class DefaultStorage(storage.FileSystemStorage):
    def __init__(self):
        super(DefaultStorage, self).__init__()
        self.encryptor = Fernet(settings.ENCRYPTION_KEY)

    def _save(self, name, content):
        encrypted = self.encryptor.encrypt(content.file.read())
        content.file.write(encrypted)
        print(content.file.read() == encrypted)
        return super(DefaultStorage, self)._save(name, content)

    def _open(self, name, mode='rb'):
        encrypted = open(self.path(name), mode).read()
        return File(self.encryptor.decrypt(encrypted))

    def get_available_name(self, name, max_length=None):
        # we return a hash of the file given,
        # in case we miss out on uniqueness, django calls
        # the get_alternative_name method
        dir_name, file_name = os.path.split(name)
        file_root, file_ext = os.path.splitext(file_name)

        file_root = hashlib.md5(file_root.encode()).hexdigest()
        name = os.path.join(dir_name, file_root + file_ext)
        return super(DefaultStorage, self).get_available_name(name, max_length)

    def get_alternative_name(self, file_root, file_ext):
        # we insert a random uuid hex string into the given
        # file name before returning the same back
        return '%s%s%s' % (file_root, uuid.uuid4().hex, file_ext)

I am overwriting the _save and _open methods here, but the class doesn't work as expected.我在这里覆盖了_save_open方法,但是 class 没有按预期工作。

Under the save method, I want to encrypt the contents of the file, but when I print this:在保存方法下,我想加密文件的内容,但是当我打印这个时:

print(content.file.read() == encrypted)

It returns false.它返回假。 This means that the file isnt even being encrypted in the firs place.这意味着文件甚至没有被加密。 What am I doing wrong here?我在这里做错了什么? Same for _open method? _open方法也一样? Can someone please help me?有人可以帮帮我吗? thanks a lot!多谢!

EDIT编辑

    def _save(self, name, content):
        initial = content.file
        encrypted = self.encryptor.encrypt(content.file.read())
        content.file.write(encrypted)
        # the temporary file is already stored in the path
        # content.file.name
        # we need to write to this directory
        print(content.file.seek(0) == encrypted)
        return super(DefaultStorage, self)._save(name, content)

this print statement also returns False此打印语句也返回 False

EDIT 2编辑 2

When I removed the existing _open method, I found out that the file could still be retrieved (without decryption).当我删除现有的_open方法时,我发现仍然可以检索该文件(无需解密)。 This means that the file isn't even being encrypted.这意味着该文件甚至没有被加密。 Any idea why?知道为什么吗? Can someone please help me?有人可以帮帮我吗?

The _save method: _save 方法:

def _save(self, name, content):
        encrypted = self.encryptor.encrypt(content.file.read())
        content.file.write(encrypted)
        return super(DefaultStorage, self)._save(name, content)

Usually, content.file.read() leaves the cursor at the end of the file.通常, content.file.read()将 cursor 留在文件末尾。

If you want to read the file again, you need to move the cursor to the start;如果要再次读取文件,需要将cursor移到开头; otherwise, .read() will just return empty, because there is nothing after the end of the file.否则, .read()只会返回空,因为文件末尾没有任何内容。

content.file.seek(0)                     # places cursor at the start
print(content.file.read() == encrypted)  # reads file again

This can be done using content.file.seek(0) (place cursor at position 0), or by closing and opening the file again.这可以使用content.file.seek(0) (将 cursor 放在 position 0 处)或通过再次关闭并打开文件来完成。


But careful, reading and writing the same file can be tricky and cause problems.但要小心,读取和写入同一个文件可能会很棘手并导致问题。 Rather write to an aux file and replace the original file with the new file afterwards.而是写入辅助文件,然后用新文件替换原始文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM