I want to store uploaded files in encrypted format. I want encrypt all kind
of files(PDF, jpg, docx, etc) . And while downloading it should download
decrypted file. Currently I am using "openssl unix command ( openssl enc
-aes-256-cbc -salt -in input_file -out output_file -k key) to decrypt file.
When I upload file using SQLFORM ,I am decrypting file
"tablename.fieldname.xxxxxx.file_extension" and then rename decrypted file
with original file name (tablename.fieldname.xxxxxx.file_extension) .
db table :
contract = db.define_table(
'contracts',
Field('contract_filename', 'text', requires=IS_NOT_EMPTY()),
Field('contract', 'upload', requires=IS_NOT_EMPTY(), autodelete=True))
Controller:
def index():
form = SQLFORM(db.contracts, fields=['contract'])
if request.vars.contract != None:
# Store original file name in db
form.vars.contract_filename = request.vars.contract.filename
if form.process().accepted:
doc_path = os.path.join(request.folder, 'uploads',
form.vars.contract)
# encrypted file with prefix "temp_"
encrypted_doc_path = os.path.join(request.folder, 'uploads',
"temp_" + form.vars.contract)
# encrypt(input_file, output_file, Key)
encrypt(doc_path, encrypted_doc_path, KEY)
# Rename decrypted file with original file name(without temp_)
os.rename(encrypted_doc_path, doc_path)
return dict(form=form)
So when we download file using default download controller, we will get
decrypted file.
I wrote my custom download controller which will decrypt file and then
download file. So this controller decrypts file and generate new file with
human readable data (original file) and deletes it after downloading file
so that only encrypted file is stored on server.
download controller :
def get():
"""
allows downloading of uploaded files
http://..../[app]/default/download/[filename]
"""
encrypted_file = request.args[0]
decrypted_file = "temp_" + request.args[0]
doc_path = os.path.join(request.folder, 'uploads', encrypted_file)
decrypted_doc_path = os.path.join(request.folder, 'uploads',
decrypted_file)
# decrypt(input_file, output_file, Key)
decrypt(doc_path, decrypted_doc_path, KEY)
response.headers['ContentType'] = "application/octet-stream"
response.headers['Content-Disposition'] = "attachment; filename=" +\
request.vars.filename
fh = open(decrypted_doc_path)
os.remove(decrypted_doc_path)
return response.stream(fh)
Decrypt / encrypt functions:
def encrypt(input_file, output_file, key):
""" Encrypt input file using AES-256 and create .enc file"""
command = "openssl enc -aes-256-cbc -salt -in %s -out %s -k %s" %
(input_file, output_file, key)
command_ls = command.split(' ')
ps = subprocess.Popen(command_ls, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
output, error = ps.communicate()
if error:
return False
else:
return True
def decrypt(input_file, output_file, key):
""" Decrypt .enc file to original file"""
command = "openssl enc -aes-256-cbc -salt -d -in %s -out %s -k %s" %
(input_file, output_file, key)
command_ls = command.split(' ')
ps = subprocess.Popen(command_ls, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
output, error = ps.communicate()
if error:
return False
else:
return True
Is there any better approach to store files in encrypted format on server
and decrypt while downloading.
--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.