A slight improvement of dinamic's function to create a key:
I think the weak point is that capitals are always used in the same part of the string. The following code capitalizes random characters of the string, making the key less predictable:
<?php
$key = substr($key1, 0, $ks/2) . substr($key2, (round(strlen($key2) / 2)), $ks/2);
$key = substr($key.$key1.$key2.$key1,0,$ks);
$buffer = str_split($key);
$limit = count($buffer)-1;
srand((float)microtime() * 1000000);
$end = rand(0, $limit);
$a = 0;
// replace random chars with capitals
while ($a < $end) {
list($usec, $sec) = explode(' ', microtime());
$seed = ((float)$sec) + ((float) $usec * 100000);
mt_srand($seed);
$index = mt_rand(0,$limit);
$buffer[$index] = strtoupper($buffer[$index]);
$a++;
}
$key = join('', $buffer);
?>
mcrypt_module_open
(PHP 4 >= 4.0.2, PHP 5)
mcrypt_module_open — Ouvre le module de l'algorithme et du mode à utiliser
Description
mcrypt_module_open() ouvre le module de l'algorithme et du mode à utiliser. Le nom de l'algorithme est spécifié par le paramètre algorithm (par exemple : "twofish"), ou bien une des constantes MCRYPT_ciphername. La bibliothèque est refermée en appelant mcrypt_module_close, mais il n'est pas nécessaire d'appeler cette fonction si mcrypt_generic_end() est utilisé. Normalement, mcrypt_module_open() retourne un pointeur de chiffrement, ou bien FALSE en cas d'erreur.
algorithm_directory et mode_directory servent à repérer les modules de chiffrement. Si vous fournissez un nom de dossier, il sera utilisé. Si vous passez une chaîne vide (""), la valeur utilisé par mcrypt.algorithms_dir ou mcrypt.modes_dir sera celle indiquée dans les directives de configuration. Lorsque ces paramètres ne sont pas fournis les valeurs par défaut, compilées avec la bibliothèque, sont utilisées. (Généralement /usr/local/lib/libmcrypt).
Exemples
Exemple #1 Exemple avec mcrypt_module_open()
<?php
$td = mcrypt_module_open(MCRYPT_DES, '',
MCRYPT_MODE_ECB, '/usr/lib/mcrypt-modes');
$td = mcrypt_module_open('rijndael-256', '', 'ofb', '');
?>
La première ligne de l'exemple ci-dessus va essayer d'ouvrir le chiffrement DES, dans le dossier par défaut, et le mode EBC dans le dossier /usr/lib/mcrypt-modes. Le second exemple utilise les chaînes comme nom pour le chiffrement et le mode. Cela ne fonctionne que si l'extension est compilée avec libmcrypt 2.4.x or 2.5.x.
Exemples
Exemple #2 Utilisation de mcrypt_module_open() pour chiffrer
<?php
/* Charge un chiffrement */
$td = mcrypt_module_open('rijndael-256', '', 'ofb', '');
/* Crée le VI et détermine la taille de la clé */
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_DEV_RANDOM);
$ks = mcrypt_enc_get_key_size($td);
/* Crée la clé */
$key = substr(md5('very secret key'), 0, $ks);
/* Intialise le chiffrement */
mcrypt_generic_init($td, $key, $iv);
/* Chiffre les données */
$encrypted = mcrypt_generic($td, 'This is very important data');
/* Libère le gestionnaire de chiffrement */
mcrypt_generic_deinit($td);
/* Initialise le module de chiffrement pour le déchiffrement */
mcrypt_generic_init($td, $key, $iv);
/* Déchiffre les données */
$decrypted = mdecrypt_generic($td, $encrypted);
/* Libère le gestionnaire de déchiffrement, et ferme le module */
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
/* Affiche la chaîne */
echo trim($decrypted)."\n";
?>
Voir aussi mcrypt_module_close(), mcrypt_generic(), mdecrypt_generic(), mcrypt_generic_init(), et mcrypt_generic_deinit().
mcrypt_module_open
17-Jul-2008 12:07
13-Nov-2007 12:05
Also it should be pointed that md5() and/or sha1() should not be used while forming your key for the mcrypt. This is so because hex encoding uses a set of only 16 characters [0-9a-f], which is equivalent to 4 bits, and thus halve the strength of your encryption: 4 x 32 = 128-bit.
I have re-wrote the example shown, so here is my suggestion to get real 256-bit encryption:
<?php
$key1 = "this is a secret key";
$key2 = "this is the second secret key";
$input = "Let us meet at 9 o'clock at the secret place.";
$length = strlen($input);
/* Open the cipher */
$td = mcrypt_module_open('rijndael-256', '', 'cbc', '');
/* Create the IV and determine the keysize length, use MCRYPT_RAND
* on Windows instead */
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$ks = mcrypt_enc_get_key_size($td);
/* Create key */
$key1 = md5($key1);
$key2 = md5($key2);
$key = substr($key1, 0, $ks/2) . substr(strtoupper($key2), (round(strlen($key2) / 2)), $ks/2);
$key = substr($key.$key1.$key2.strtoupper($key1),0,$ks);
/* Intialize encryption */
mcrypt_generic_init($td, $key, $iv);
/* Encrypt data */
$encrypted = mcrypt_generic($td, $input);
/* Terminate encryption handler */
mcrypt_generic_deinit($td);
/* Initialize encryption module for decryption */
mcrypt_generic_init($td, $key, $iv);
/* Decrypt encrypted string */
$decrypted = mdecrypt_generic($td, $encrypted);
/* Terminate decryption handle and close module */
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
/* Show string */
echo "Text: ".substr($decrypted,0,$length) . "<br>";
echo "Encoded: ".$encrypted ."<br>";
echo "<br>key1: $key1 <br>key2: $key2<br>created key: $key";
?>
03-Mar-2006 12:27
In the text example:
$key = substr(md5('very secret key'), 0, $ks);
Builds a key of $ks/2 effective bytes.
Doing a trim($decrypted) will remove the null padding that may occur as a result of decryption.
The problem is if you're encrypting something like a MSWord document which can commonly end with nulls. The result $decrypted will be smaller than the original cleartext - which will then fail to open in MSOffice.
To get around this, make sure you store the length of the original cleartext, and when you decrypt it, do:
$decrypted = substr(mdecrypt_generic($td, $encrypted), 0, $originalLength);
