2

I have to encrypt a file and save it in mysql as a blob, then decrypt it and make it available for download. I save the file in a blob like so:

$certificate_tmp=$_FILES['certificate']['tmp_name'];
$certificate=openssl_encrypt(file_get_contents($certificate_tmp),$ciphers,$password_tmp);
$wpdb->insert("my_table",array("certificate"=>$certificate));

Note: I've cut unrelated code, the table is not just certificate, but I don't want this to get confusing.

This is the download php page:

$password_tmp=$_SESSION['pwd']; //decrypt password
global $wpdb; //wordpress db conncetion
$results_file = $wpdb->get_row("select * from my_table where id='$id'",ARRAY_A); //i get the id from wp's curr_user
$m_file = openssl_decrypt($results_file['certificate'],"AES-128-CBC",$password_tmp);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\certificate".$id."\"");
header('Content-Transfer-Encoding: binary');
print_r($m_file);

And everything works perfectly with text files, but the result is empty with binary files, although in the blob the binary file is there.

EDIT My guess is, as soon as I decrypt the file from the db blob, php or html (because of print_r) understands that it is a binary file and doesn't let you show it because of security reasons. You can't execute programs on the web like .exe or .bin, although the files I upload, either binary or text have no extension. From what I understand php treats binary files as strings, but file_get_contents is binary safe. I think not using blobs would be the best approach for this, but I cannot do that, I have to use blobs.

EDIT 2 The problem seems to be openssl which doesn't seem to like binary data, I've tried the same code using mcrypt and it works perfectly.

Cr1xus
  • 427
  • 3
  • 20

1 Answers1

1
  1. Make sure you are decrypting the data using the same key.
  2. Why do you use print instead of print_r?

  3. Try to add the content length:

    header('Content-Length: '.strlen(YourFileData));

  4. For more information please visit: http://www.media-division.com/the-right-way-to-handle-file-downloads-in-php/

Ahmad
  • 808
  • 9
  • 14
  • Thanks for the answer. 1. It is the same key, I use the variable `$ciphers` where i do more than one openssl. 2. I used print_r in my code, I've tried with print as well, but same thing, text files work, binary files don't. 3. I've added that as well, but still doesn't work with binary files (again text files don't have any problem being encrypted, decrypted. 4. I'll take a deep read into that, thank you. Check my edit. – Cr1xus Mar 15 '17 at 10:23