2

Usually, I use openssl_encrypt to encrypt simple string with AES in PHP, and it works pretty well.

Now I need to encrypt files with AES-256-CTR mode, but the only way to do this is to file_get_contents the entire content of the file and then send it to the openssl_encrypt function to encrypt the actual file data. The problem is this method is very "poor" because of the critical waste of memory.

1) Is there a way to work with chunked data with PHP OpenSSL ?

For example:

<?php
// ...
$f = fopen('large.iso','r');
  while(feof($f)){
    $chunk = fread($f,16);
       $cipher = openssl_encrypt(...$chunk...);
    // ... code ...
   }
    // ... more code ...
?>

2) openssl_encrypt official documentation is not published yet. Does someone could clarify the meaning of the parameters of the function for use with AES-CTR mode? Does the counter is handled automatically? Is it necessary to apply a manual XOR the data returned by the function?

Note: It is a professional project so I don't want to use phpseclib or others' "anonymous" libraries, nor do I don't want to use the command line as well.

2 Answers 2

1

Looks like for php it's not possible to use aes-256-ctr without temporary file.

But for next chiper types:

OPENSSL_CIPHER_RC2_40 
OPENSSL_CIPHER_RC2_128 
OPENSSL_CIPHER_RC2_64  
OPENSSL_CIPHER_DES 
OPENSSL_CIPHER_3DES 
OPENSSL_CIPHER_AES_128_CBC 
OPENSSL_CIPHER_AES_192_CBC  
OPENSSL_CIPHER_AES_256_CBC 

you can use generating key on the fly:

$res = openssl_pkey_new('chiper args here');
openssl_pkey_export($res, $private_key);

$public_key = openssl_pkey_get_details($res);
$public_key = $public_key["key"];

Then encrypt:

$crypted_text = openssl_get_privatekey($private_key,'your data'); 

And decrypt:

openssl_public_decrypt($crypted_text,$decrypted_text,$public_key);

So if you don't want to use files, may be switching to OPENSSL_CIPHER_AES_256_CBC will help you?

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for posting but my topic is NOT about asymmetric encryption. 1/ My first question is; is there a way to work globally (CBC,ECB,CTR,...) with chunked data with PHP OpenSSL symmetric encryption (AES) ? 2/ My second question is about the CTR mode in particular with AES symmetric encryption and how it's implemented by PHP OpenSSL. I know that PHP OpenSSL support AES-256-CTR because when I exec openssl_get_cipher_methods it's here!
1

1) It should be something like this:

function strtohex($x) {
    $s = '';
    foreach (str_split($x) as $c){
        $s.=sprintf("%02X", ord($c));
    }
    return($s);
}

$method = "aes-256-ctr"; //aes-256-cbc
echo "Selected method: ".$method."<br /><br />";
$textToEncrypt = "My chunk of data";
$iv = "1234567890123456";
$pass = 'some_pass';
$dec_iv = strtohex($iv);
$key = strtohex($pass);
$enc_data = openssl_encrypt($textToEncrypt, $method, $pass, true, $iv);
echo "Encrypted message (openssl): ".$enc_data."<br />";
$dec_data = openssl_decrypt($enc_data, $method, $pass, OPENSSL_RAW_DATA, $iv);
echo "Decrypted message (openssl): ".$dec_data."<br />";

For CTR $iv should be unique for each chunk or your data can be broken.

2) I know only abot difference betwen CBC and CTR:

For CBC, the IV must be random, but not unique. It also must not be known.

For CTR, the IV must be unique and not known, but does not need to be random.

1 Comment

The poster specifically asked about a file; and not a string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.