Django Python:如何解密 Python shell 中的 AES-CTR 模式加密文件?
Django Python: How do I decrypt an AES-CTR mode encrypted file in the Python shell?
我正在使用 https://github.com/eblocha/django-encrypted-files 加密通过 Django 中的一个简单联系表单应用程序上传到服务器的文件。 django-encrypted-files
在 CTR 模式下使用 AES 通过上传处理程序加密上传的文件,同时将文件流式传输到服务器。
我想做的是通过 FTP 下载文件并在 Python shell 中本地解密来手动解密加密文件。我不想也不需要从服务器流式解密文件或修改django-encrypted-files
;我只想在 Python shell.
本地手动下载然后解密文件
问题是我无法使用本地 Python 解密。 Cryptography 中的文档显示了使用 Python shell 中输入的示例文本进行加密和解密的示例。但是没有encrypting/decrypting一个文件的例子
下面是我在 Python shell 中尝试使用的代码。通过Django上传的原始文件是uploaded_file.txt。从服务器下载的加密文件为encrypted.txt;用于保存解密文本的文件是 decrypted.txt.
但是当我尝试下面的代码时,decrypted.txt 是空的。这是写文件的问题吗?或者 iv
?
有问题
在本地解密 AES-CTR 模式文件的工作示例是什么 Python shell?
uploaded_file.txt: https://paste.c-net.org/MiltonElliot
encrypted.txt: https://paste.c-net.org/ChasesPrints
Python shell:
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
key = b'\x1a>\xf8\xcd\xe2\x8e_~V\x14\x98\xc2\x1f\xf9\xea\xf8\xd7c\xb3`!d\xd4\xe3+\xf7Q\x83\xb5~\x8f\xdd'
iv = os.urandom(16)
cipher = Cipher(algorithms.AES(key), modes.CTR(iv))
decryptor = cipher.decryptor()
openfile = open("encrypted.txt", 'rb')
savefile = open("decrypted.txt", "wb")
read = openfile.read()
savefile.write(read[16:])
445 // output
exit
但是 decrypted.txt 文件是空的。
这可能相关也可能不相关;这是在流式传输到服务器时加密的函数:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from django.core.files.uploadhandler import FileUploadHandler
class EncryptedFileUploadHandler(FileUploadHandler):
"""Encrypt data as it is uploaded"""
def __init__(self, request=None, key=None):
super().__init__(request=request)
self.key = key or settings.AES_KEY
def new_file(self, *args, **kwargs):
self.nonce = os.urandom(16)
self.encryptor = Cipher(algorithms.AES(self.key),modes.CTR(self.nonce)).encryptor()
self.nonce_passed = False
return super().new_file(*args,**kwargs)
def receive_data_chunk(self, raw_data, start):
if not self.nonce_passed:
self.nonce_passed = True
return self.nonce + self.encryptor.update(raw_data)
else:
return self.encryptor.update(raw_data)
def file_complete(self, file_size):
return
在加密过程中,IV 和密文连接在一起:IV || ciphertext
。在解密过程中,使用了随机 IV,这是错误的。相反,必须应用加密的 IV。为此,必须将 IV 和密文分开。
此外,必须调用 update()
和 finalize()
方法,它们执行实际的解密。
以下代码与您的代码基本匹配,由缺少的部分扩展:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
# Read ciphertext
openfile = open("encrypted.txt", 'rb')
read = openfile.read()
openfile.close()
# Separate IV and ciphertext; decrypt
iv = read[:16]
ciphertext = read[16:]
key = b'\x1a>\xf8\xcd\xe2\x8e_~V\x14\x98\xc2\x1f\xf9\xea\xf8\xd7c\xb3`!d\xd4\xe3+\xf7Q\x83\xb5~\x8f\xdd'
cipher = Cipher(algorithms.AES(key), modes.CTR(iv))
decryptor = cipher.decryptor()
decrypted = decryptor.update(ciphertext) + decryptor.finalize()
# Store decrypted data
savefile = open("decrypted.txt", "wb")
savefile.write(decrypted)
savefile.close()
此代码成功解密了链接文件中的密文(使用发布的密钥)。
我正在使用 https://github.com/eblocha/django-encrypted-files 加密通过 Django 中的一个简单联系表单应用程序上传到服务器的文件。 django-encrypted-files
在 CTR 模式下使用 AES 通过上传处理程序加密上传的文件,同时将文件流式传输到服务器。
我想做的是通过 FTP 下载文件并在 Python shell 中本地解密来手动解密加密文件。我不想也不需要从服务器流式解密文件或修改django-encrypted-files
;我只想在 Python shell.
问题是我无法使用本地 Python 解密。 Cryptography 中的文档显示了使用 Python shell 中输入的示例文本进行加密和解密的示例。但是没有encrypting/decrypting一个文件的例子
下面是我在 Python shell 中尝试使用的代码。通过Django上传的原始文件是uploaded_file.txt。从服务器下载的加密文件为encrypted.txt;用于保存解密文本的文件是 decrypted.txt.
但是当我尝试下面的代码时,decrypted.txt 是空的。这是写文件的问题吗?或者 iv
?
在本地解密 AES-CTR 模式文件的工作示例是什么 Python shell?
uploaded_file.txt: https://paste.c-net.org/MiltonElliot
encrypted.txt: https://paste.c-net.org/ChasesPrints
Python shell:
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
key = b'\x1a>\xf8\xcd\xe2\x8e_~V\x14\x98\xc2\x1f\xf9\xea\xf8\xd7c\xb3`!d\xd4\xe3+\xf7Q\x83\xb5~\x8f\xdd'
iv = os.urandom(16)
cipher = Cipher(algorithms.AES(key), modes.CTR(iv))
decryptor = cipher.decryptor()
openfile = open("encrypted.txt", 'rb')
savefile = open("decrypted.txt", "wb")
read = openfile.read()
savefile.write(read[16:])
445 // output
exit
但是 decrypted.txt 文件是空的。
这可能相关也可能不相关;这是在流式传输到服务器时加密的函数:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from django.core.files.uploadhandler import FileUploadHandler
class EncryptedFileUploadHandler(FileUploadHandler):
"""Encrypt data as it is uploaded"""
def __init__(self, request=None, key=None):
super().__init__(request=request)
self.key = key or settings.AES_KEY
def new_file(self, *args, **kwargs):
self.nonce = os.urandom(16)
self.encryptor = Cipher(algorithms.AES(self.key),modes.CTR(self.nonce)).encryptor()
self.nonce_passed = False
return super().new_file(*args,**kwargs)
def receive_data_chunk(self, raw_data, start):
if not self.nonce_passed:
self.nonce_passed = True
return self.nonce + self.encryptor.update(raw_data)
else:
return self.encryptor.update(raw_data)
def file_complete(self, file_size):
return
在加密过程中,IV 和密文连接在一起:IV || ciphertext
。在解密过程中,使用了随机 IV,这是错误的。相反,必须应用加密的 IV。为此,必须将 IV 和密文分开。
此外,必须调用 update()
和 finalize()
方法,它们执行实际的解密。
以下代码与您的代码基本匹配,由缺少的部分扩展:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
# Read ciphertext
openfile = open("encrypted.txt", 'rb')
read = openfile.read()
openfile.close()
# Separate IV and ciphertext; decrypt
iv = read[:16]
ciphertext = read[16:]
key = b'\x1a>\xf8\xcd\xe2\x8e_~V\x14\x98\xc2\x1f\xf9\xea\xf8\xd7c\xb3`!d\xd4\xe3+\xf7Q\x83\xb5~\x8f\xdd'
cipher = Cipher(algorithms.AES(key), modes.CTR(iv))
decryptor = cipher.decryptor()
decrypted = decryptor.update(ciphertext) + decryptor.finalize()
# Store decrypted data
savefile = open("decrypted.txt", "wb")
savefile.write(decrypted)
savefile.close()
此代码成功解密了链接文件中的密文(使用发布的密钥)。