1

I am creating a random key, then i want to encrypt it using a good algorithm, then I want to encrypt the data with this encrypted key. My code is:

$iv=16; //128bits
$datakey = base64_encode(openssl_random_pseudo_bytes($iv,$strong));
$datakey = md5($datakey);
$finaldata= mcrypt_encrypt(MCRYPT_BLOWFISH, $datakey, $stringtobeencoded, MCRYPT_MODE_CFB);

Error:

Encryption mode requires an initialization vector of size 8

How to accomplish my requirement?

CerebralFart
  • 3,336
  • 5
  • 26
  • 29
ITSagar
  • 673
  • 2
  • 10
  • 29

3 Answers3

11

i want to encrypt it using a good algo

The snippet you included in your question is not secure. I highly recommend:

  1. Don't use mcrypt.
  2. Refer to the example code in this linked answer for how to encrypt securely.

But the error you're getting is that Blowfish-CFB expects a key and an IV, and you only provided a key.

Scott Arciszewski
  • 33,610
  • 16
  • 89
  • 206
6

The actual error—Encryption mode requires an initialization vector of size 8—is not an invalid key size, it is the lack of an IV.

CFB mode requires an IV (Initialization Vector). The IV size is generally the same as the block size, 64-bits for Blowfish, 128-bits for AES.

It is generally best not to use Blowfish for encryption, even its author uses AES these days.

When saving a password verifier just using a hash function is not sufficient and just adding a salt does little to improve the security. Instead iterate over an HMAC with a random salt for about a 100ms duration and save the salt with the hash. Better yet use a function such as PBKDF2, Rfc2898DeriveBytes, Argon2, password_hash, Bcrypt or similar functions. With PHP use password_hash and password_verify, the pair are secure and easy to use. The point is to make the attacker spend substantial time finding passwords by brute force.

It is best not to use PHP mcrypt, it is abandonware, has not been updated in years and does not support standard PKCS#7 (née PKCS#5) padding, only non-standard null padding that can't even be used with binary data. mcrypt has many outstanding bugs dating back to 2003. The mcrypt-extension is deprecated was removed in PHP 7.2. Instead consider using defuse or RNCryptor, they provide a complete solution and are being maintained and is correct.

zaph
  • 111,848
  • 21
  • 189
  • 228
1

You have a lot going on with your example, since mcrypt_* is deprecated, this example uses openssl_* functions instead. To skip IV creation (less secure but easier) use the following:

$plainText = 'Hello world';
$key  = 'my-secret-encrpytion-key';
$algo = 'BF-CFB'; // blowfish cfb

$cypherText = openssl_encrypt($plainText, $algo, $key);
echo base64_encode($cypherText); // ZTVtdWNMRUp5N1dwZ2NFPQ==

echo openssl_decrypt($cypherText, $algo, $key);

For a more complete implementation, including generation of the $iv as you were attempting to do in your original question, the following code will work:

$plainText = 'Hello world';
$key  = 'my-secret-encrpytion-key';
$algo = 'BF-CFB'; // blowfish cfb

$ivLen = openssl_cipher_iv_length($algo); // $ivLen = 8
$iv = openssl_random_pseudo_bytes($ivLen);
$cypherText = openssl_encrypt($plainText, $algo, $key, 0, $iv);

echo base64_encode($cypherText); // V3JtL1crWHZKL1lEeGJBPQ==

echo openssl_decrypt($cypherText, $algo, $key, 0, $iv);

This was edited to correct variable names that were incorrect.

Erik Giberti
  • 1,235
  • 9
  • 11
  • Hi, what is $cipher here? where is its value coming from? – ITSagar Oct 20 '18 at 06:54
  • It says: Warning: openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended in .... How to avoid this? – ITSagar Oct 20 '18 at 07:11
  • Sorry, that should have been `$algo`; one of the available algorithms supported by your system, see possible values from [`openssl_get_cipher_methods()`](http://php.net/manual/en/function.openssl-get-cipher-methods.php) – Erik Giberti Oct 21 '18 at 14:57
  • Use the second code example to eliminate the empty initialization vector message. – Erik Giberti Oct 21 '18 at 14:58
  • But problem with second approach is that it will generate a random IV everytime operation is performed. I will have to store the IV within Database/ File/ Registry which can be read by a normal hacker too. So I wanted to encrypt the secret key as well as IV before using them for encrypting the data. Any ideas for this? – ITSagar Oct 23 '18 at 12:20