django - django在存储前加密文件
问题描述
所以我想在存储在 django 之前加密文件并在检索时解密它们。
我正在使用相同的自定义存储类和加密模块。
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)
我在这里覆盖了_save
and_open
方法,但是该类没有按预期工作。
在保存方法下,我想加密文件的内容,但是当我打印这个时:
print(content.file.read() == encrypted)
它返回假。这意味着文件甚至没有被加密。我在这里做错了什么?方法一样_open
吗?有人可以帮帮我吗?多谢!
编辑
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)
此打印语句也返回 False
编辑 2
当我删除现有_open
方法时,我发现仍然可以检索文件(无需解密)。这意味着该文件甚至没有被加密。知道为什么吗?有人可以帮帮我吗?
_save 方法:
def _save(self, name, content):
encrypted = self.encryptor.encrypt(content.file.read())
content.file.write(encrypted)
return super(DefaultStorage, self)._save(name, content)
解决方案
通常,content.file.read()
将光标留在文件末尾。
如果要再次读取文件,需要将光标移到开头;否则,.read()
只会返回空,因为文件结束后没有任何内容。
content.file.seek(0) # places cursor at the start
print(content.file.read() == encrypted) # reads file again
这可以使用content.file.seek(0)
(将光标放在位置 0)或通过关闭并再次打开文件来完成。
但要小心,读取和写入同一个文件可能会很棘手并导致问题。而是写入辅助文件,然后用新文件替换原始文件。
推荐阅读
- reactjs - 在 react-select-search 输入名称时,结果被填充
- javascript - 如何从具有不同域的 iFrame 发送帖子消息?
- php - 如何解析和获取来自给定网址的元标记的图像和描述?
- laravel - Laravel 存储图像未加载
- php - 如何在共享主机中使用 PHP 在视频上添加文本水印
- c++ - С++ Microsoft MFC TreeView 图标
- docker-compose - Jenkins CI 与 docker-compose - 如何正确停止容器
- java - google Safebrowsing api v4 总是返回空响应
- python - Remove quotations that surrounds substring but keep standalone quotes
- reactjs - 反应按钮 onClick 正确绑定,但无法正常工作