The mcrypt implementation of RC2 algorithm supports an effective key length of 1024 bits only.
It is however possible to use an effective key length in 1..1024 bits, by transforming the key before use as follows:
<?php
function transformKey($key, $effKeyLen)
{
$pitable = array(
0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13, 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B, 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C, 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1, 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57, 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7, 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7, 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74, 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC, 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A, 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE, 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C, 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0, 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD);
$invpitable = array_flip($pitable);
// Apply the regular RC2 key expansion algorithm.
$t = strlen($key);
$key = array_values(unpack('C*C', $key));
for ($i = $t; $i < 128; $i++)
$key[$i] = $pitable[($key[$i - 1] + $key[$i - $t]) & 0xFF];
$t8 = ($effKeyLen + 7) >> 3;
$tm = 0xFF >> (8 * $t8 - $effKeyLen);
$i = 128 - $t8;
$key[$i] = $pitable[$key[$i] & $tm];
while ($i--)
$key[$i] = $pitable[$key[$i + 1] ^ $key[$i + $t8]];
// Map the first byte: this operation will be undone by
// mcrypt internals.
$key[0] = $invpitable[$key[0]];
// Return the transformed key as a string.
array_unshift($key, 'C*');
return call_user_func_array('pack', $key);
}
// Usage example
$r = mcrypt_module_open(MCRYPT_RC2, $algoDir, $mode, $modeDir);
mcrypt_generic_init($r, transformKey($originalKey, $effectiveKeyLength), $iv);
?>
mcrypt_generic_init
(PHP 4 >= 4.0.2, PHP 5)
mcrypt_generic_init — Esta función inicializa todos los buffers requeridos para el cifrado
Descripción
$td
, string $key
, string $iv
)Se necesita invocar esta función antes de cada llamada a mcrypt_generic() o mdecrypt_generic().
Parámetros
-
td -
El descriptor de cifrado.
-
key -
La longitud máxima de la clave debería ser la misma obtenida al invocar a mcrypt_enc_get_key_size() y todos los valores menores son legales.
-
iv -
El IV debería tener normalmente el tamaño del bloque del algoritmo, pero debe obtener el tamaño tras invocar a mcrypt_enc_get_iv_size(). El IV es ignorado en modo ECB. El IV DEBE existir en modo CFB, CBC, STREAM, nOFB Y OFB. Requiere ser aleatorio y único (pero no secreto). El mismo IV debe ser utilizado para el cifrado/desencriptado. Si no se desea usarlo se debería setearlo con ceros, pero no es recomendado.
Valores devueltos
Esta función devuelve un valor negativo en caso de error: -3 cuando la
longitud es incorrecta, -4 cuando hubo un problema de asignación de memoria
y todos los demás valores retornados son errores desconocidos. Si ocurre un
error, se imprimirá el correspondiente warning. FALSE es devueto si fueron
pasados argumentos incorrectos.
If you write error-checking into your code, be warned that this function returns FALSE on some errors, and 0 on success, hence
mcrypt_generic_init( $a, $b, $c ) or die( "Oops");
ALWAYS exits with the error message "Oops", and
(mcrypt_generic_init( $a, $b, $c ) >= 0 ) or die( "Oops");
Sometimes continues when mcrypt_generic_init() actually failed.
To check for successful init use something like:
$s = mcrypt_generic_init( $a, $b, $c );
if( ($s < 0) || ($s === false))
die( "Really an error" );
