Estoy tratando de cifrar/descifrar una cadena mediante AES de 128 bits de cifrado (BCE). Lo que quiero saber es como puedo agregar/quitar el relleno de PKCS7. Parece que la extensión Mcrypt puede tomar el cuidado de cifrado/descifrado, pero el relleno tiene que ser añadido/eliminado manualmente.
Alguna idea?
Sólo una nota: Si no se puede cambiar, el uso de otro de modo que el BCE (es inseguro).
No, no se puede cambiar, es lo que el sistema del cliente depende. Cualquier posibilidad de que usted podría guiarme con el relleno cosa?
Me refería a AES, fijo.
No utilice el modo de ECB. Si el cliente piensa que necesitan BCE, están equivocados. Usar el CTR o CBC, asegúrese de que la autenticación de su ciphertexts.
No, no se puede cambiar, es lo que el sistema del cliente depende. Cualquier posibilidad de que usted podría guiarme con el relleno cosa?
Me refería a AES, fijo.
No utilice el modo de ECB. Si el cliente piensa que necesitan BCE, están equivocados. Usar el CTR o CBC, asegúrese de que la autenticación de su ciphertexts.
OriginalEl autor Click Upvote | 2011-09-06
Vamos a ver. PKCS #7 se describe en el RFC 5652 (Sintaxis de Mensajes Criptográficos).
El esquema de relleno sí se da en la sección 6.3. Contenido-Proceso de cifrado. Que esencialmente dice: anexar que tantos bytes como sea necesario para llenar el dado por el tamaño de bloque (al menos uno), y cada uno de ellos debe tener la longitud de relleno como valor.
Por lo tanto, mirando a la última descifrar byte sabemos cuántos bytes a la franja. (También se podría comprobar que todos ellos tienen el mismo valor.)
Ahora podía darle un par de funciones de PHP para hacer esto, pero mi PHP es un poco oxidado. Para hacerlo usted mismo (a continuación, siéntase libre de editar mi respuesta a agregar), o eche un vistazo a la el usuario contribuido notas a la mcrypt documentación – bastante algunos de ellos son de alrededor de relleno y proporcionar una implementación de relleno PKCS #7.
Así que, vamos a ver en el primera nota en detalle:
Esto hace que el tamaño de bloque del algoritmo usado. En su caso, utilizaría
aes
orijndael_128
en lugar dedes
, supongo (yo no prueba). (En su lugar, usted podría simplemente tomar16
aquí para AES, en lugar de invocar a la función.)Calcula el relleno de tamaño.
strlen($str)
es la longitud de su base de datos (en bytes),% $block
da el resto modulo$block
, es decir, el número de bytes de datos en el último bloque.$block - ...
da, por tanto, el número de bytes necesarios para llenar este último bloque (este es un número entre1
y$block
, ambos inclusive).str_repeat
produce una cadena que consiste en una repetición de la misma cadena, aquí una repetición de la carácter dado por$pad
,$pad
veces, es decir, una cadena de longitud$pad
, lleno de$pad
.$str .= ...
anexa a esta cadena de relleno con los datos originales.Aquí es la misma encriptación. Uso
MCRYPT_RIJNDAEL_128
en lugar deMCRYPT_DES
.Ahora la otra dirección:
El descifrado. (Usted, por supuesto, el cambio de algoritmo, como en el anterior). $str es ahora la cadena descifrada, incluyendo el relleno.
Esto es, nuevamente, el tamaño de bloque. (Ver más arriba).
Este se ve un poco extraño. Mejor escribir en varios pasos:
$len
es ahora la longitud del collar de la cadena, y$str[$len - 1]
es el último carácter de esta cadena.ord
la convierte en un número. Por lo tanto$pad
es el número que hemos utilizado anteriormente como el relleno de valor para el relleno, y esta es la longitud de relleno.Así que ahora tenemos que cortar los últimos
$pad
bytes de la cadena. (En lugar destrlen($str)
también se podrían escribir$len
aquí:substr($str, 0, $len - $pad)
.).Nota que en lugar de utilizar
substr($str, $len - $pad)
, también se puede escribirsubstr($str, -$pad)
, como elsubstr
función en PHP tiene un especial de manejo para los operandos y argumentos, a contar desde el final de la cadena. (No sé si esto es más o menos eficiente que la obtención de la longitud de la primera y y calcular el índice de forma manual.)Como se dijo antes, y señaló en el comentario por rossum, en lugar de simplemente eliminando el relleno como se hace aquí, se debe verificar que es correcta – es decir, mirar
substr($str, $len - $pad)
, y comprobar que todos sus bytes sonchr($pad)
. Esto sirve como un leve cheque contra la corrupción (aunque esta comprobación es más eficaz si se utiliza un modo de encadenamiento en lugar del BCE, y no es un reemplazo para un verdadero MAC).(Y aún así, dígale a su cliente que debería pensar en cambiar a una más segura de modo que no es el BCE.)
Al retirar el relleno no debes quitarlo. Usted debe buscar de que es correcta. Si es que, a continuación, proceder, si no es correcto, a continuación, borrar el texto descifrado y lanzar un margen de error.
WARNING: si un atacante puede probar por la incorrecta acolchados en línea, a continuación, un atacante puede crear padding oracle ataques que puede destruir por completo a la confidencialidad. Usar un MAC o HMAC sobre el IV y el texto cifrado para evitar este escenario.
En su descifrar función usted está calculando $bloque, pero no se utiliza en la función. Por qué?
Para ser honesto, no tengo idea. He copiado el código de usuario aportado por los comentarios de la página vinculada de PHP, doc, y acaba de agregar mis comentarios. (El vinculado comentario es desaparecido desde entonces o el Id de la página ha cambiado.)
OriginalEl autor Paŭlo Ebermann
He creado dos métodos para realizar el relleno y unpadding. Las funciones están documentadas mediante
phpdoc
y requiere PHP 5. Como te darás cuenta el unpad función contiene una gran cantidad de manejo de excepciones, la generación de no menos de 4 mensajes diferentes para cada posible error.Para obtener el tamaño de bloque para mcrypt PHP, puede utilizar
mcrypt_get_block_size
, que también define el tamaño de bloque en bytes en lugar de bits.Esto no invalida la respuesta de Paŭlo Ebermann de alguna manera, que es básicamente la misma respuesta en el código & phpdoc en lugar de como una descripción.
Nota que devolver un margen de error de un atacante podría resultar en un relleno de oracle ataque que rompe completamente CBC (cuando CBC se utiliza en lugar del BCE o de un seguro de cifrado autenticado).
OriginalEl autor Maarten Bodewes
Basta con llamar a la siguiente función después de descifrar los datos
OriginalEl autor Hari Das