views:

48

answers:

2

Hi,

I'm looking for a way to open encrypted files that are stored on a server. I'm using mcrypt to encrypt the files.

I was initially going to create a class that would open the file, decrypt it, write it to a new location, then open that. But I have convinced myself there is a better way (I just don't know what it is). It seems like there should be a way to stream it (?) to the browser once it's decrypted.

The initial setup would just link to the file location and the browser would take over (e.g. .pdf files would bring up a dialogue offering to open or save the file). If possible, I'd like it to do the same after decoding.

Pointers? Advice? Bueller?

Thanks!


edit:

This is what is working for now:

function decryptFile($path){
    $folder=BASE_PATH.$path.'/'.$this->uri->segment(4);
    if(!file_exists($folder.'/tmp')){
        mkdir($folder.'/tmp', 0700); 
        chmod($folder.'/tmp', 0700);
    }
    $tmpfn=BASE_PATH.$path.'/'.$this->uri->segment(4).'/tmp/'.$this->uri->segment(5);
    $p=BASE_PATH.$path.'/'.$this->uri->segment(4).'/'.$this->uri->segment(5);
    $pc=file_get_contents($p) or die ('no gfc');
    $pcue=$this->encrypt->decode($pc,$this->e_key) or die ('no decode');
    $pp=fopen($tmpfn,"w") or die ('no fopen'.$tmpfn);
    fwrite($pp,$pcue) or die ('no write');
    fclose($pp);

    if (file_exists($tmpfn)) {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($tmpfn));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($tmpfn));
        ob_clean();
        flush();
        readfile($tmpfn);
        unlink($tmpfn);
        exit;
    }
}  

But another side effect of doing it this way (I guess) is that now instead of getting an open or save dialogue, the only option is to save the file. I'd rather have the option if possible.


edit - final code:

function decryptFile(){
    extract($_POST);
    $folder = $this->uri->segment(3);
    $clientFolder = $this->uri->segment(4);
    $fileName = $this->uri->segment(5);
    $filePath=BASE_PATH.$folder.'/'.$clientFolder.'/'.$fileName;
    $fileContents=file_get_contents($filePath) or die ('Could not get file contents.');
    $ue_fileContents=$this->encrypt->decode($pc,$this->e_key) or die ('Could not decode.');
    header('Content-Description: File Transfer');
    header('Content-Type: '.$type);
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . strlen($ue_fileContents));
    echo $ue_fileContents;
    exit;
}
+1  A: 

But another side effect of doing it this way (I guess) is that now instead of getting an open or save dialogue, the only option is to save the file. I'd rather have the option if possible

Try to replace

header('Content-Type: application/octet-stream');

with the actual type of the file. For instance, if it's a PDF:

header('Content-type: application/pdf');

You may also want to drop the line:

header('Content-Disposition: attachment; filename='.basename($tmpfn));

so that no dialog is shown by the browser.

Artefacto
+1  A: 

Why do you have to write to a temporary file? You can simply do something like this,

function decryptFile($path){
    $folder=BASE_PATH.$path.'/'.$this->uri->segment(4);
    $tmpfn=BASE_PATH.$path.'/'.$this->uri->segment(4).'/tmp/'.$this->uri->segment(5);
    $p=BASE_PATH.$path.'/'.$this->uri->segment(4).'/'.$this->uri->segment(5);
    $pc=file_get_contents($p) or die ('no gfc');
    $pcue=$this->encrypt->decode($pc,$this->e_key) or die ('no decde');
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($tmpfn));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . strlen($pcue));
        echo $pcue;
        exit;

}  
ZZ Coder