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 web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to