Pregunta

Necesito medio de cifrado fuerte en serverside, por lo que pensé que iba a utilizar mcrypt con PHP. Si utilizo las funciones a continuación el principio de mi cadena original se convierte en basura binaria después de descifrarlo. (Esto no es el problema habitual de ser anexado adicional de basura, en lugar de mi cadena es alterados .) De acuerdo con la documentación, MCRYPT_ENCRYPT () debería haber rellenado caracteres son suficientes para cubrir la tamaño del bloque del algoritmo seleccionado, pero sospecho que no funciona.

Sin embargo, si la pista de I manualmente al tamaño de bloque de 128 bits (16 bytes) de Rijndael, que no funciona bien. La única manera que puedo conseguir que esto funcione es anteponiendo un trozo de cuerda lo suficiente para (probable) cubrir el bloque garbaged y añadir un prefijo conocido como "# DATOS" entre esta cadena y mis datos. Después de descifrado ese bloque ha sido parcialmente destrozada pero mi prefijo y todos los datos después de que se ha descifrado correctamente.

$GLOBALS['encryptionmarker'] = 'DATA#';

function encrypt($plain, $key) {
    /*
    // workaround because beginning of decrypted string is being mangled
    // so we simply prefix with some text plus marker
    $prefix = str_pad('', 128, '#', STR_PAD_RIGHT).$GLOBALS['encryptionmarker'];
    $plain = $prefix.$plain;
    */

    $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $plain, MCRYPT_MODE_CFB,
        mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB),
        MCRYPT_DEV_URANDOM));

    return $encrypted;
}

function decrypt($encrypted, $key) {
    $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_CFB,
        mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB),
        MCRYPT_DEV_URANDOM));

    /*
    // workaround: remove garbage
    $pos = strpos($decrypted, $GLOBALS['encryptionmarker']);
    $decrypted = trim(substr($decrypted, $pos + strlen($GLOBALS['encryptionmarker'])));
    */

    return $decrypted;
}

¿Qué pasa con mis funciones? ¿Por qué tengo que anteponer mis datos como que (creo que es una solución sucia, así que me gustaría para solucionarlo)?

no es el problema El almacenamiento de los datos cifrados; descifrar inmediatamente después del cifrado sin almacenarlo a una base de datos en los resultados de los mismos errores.

¿Fue útil?

Solución

Su problema es que se está generando un nuevo diferente IV, al azar en el lado receptor. Esto no funciona, como hemos visto.

El receptor necesita conocer el IV que el remitente utiliza; así que hay que enviarlo junto con los datos cifrados y pasarlo a mcrypt_decrypt().

Tenga en cuenta que también debe utilizar mhash() con una clave (una clave diferente a la clave de cifrado) para generar una HMAC sobre el mensaje y comprobar que en el lado receptor. Si no lo hace, un hombre-en-el-medio puede modificar trivialmente partes de su mensaje sin que lo detecte.

Otros consejos

Utilice el mismo IV en en- y el descifrado. El IV no es un secreto compartido, pero tiene que ser compartida. Puede consultar Wikipedia: IV

$IV = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB),
      MCRYPT_DEV_URANDOM));

El IV se debe transferir una vez. Es posible que desee incrementar el valor de IV para cada paquete. Pero esto se puede hacer de forma independiente en ambos lados.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top