Este escrito fue aprobado por nuestros especialistas para asegurar la exactitud de este enunciado.
Solución:
El vector de inicialización es parte de lo que hace que AES funcione en modo CBC (Cipher Block Chaining): los IV no son exclusivos de OpenSSL. CBC funciona haciendo XORing del bloque anterior con el bloque actual. El primer bloque no tiene un bloque anterior, por lo que el IV sirve para ese propósito.
Por qué esto es necesario requiere un poco de comprensión de cómo funcionan los cifrados de bloque. Sin este encadenamiento y IV, nos quedamos con un modo de AES llamado ECB, o Electronic Code Book. ECB tiene debilidades que permiten un ataque de texto sin formato elegido, entre muchos otros problemas.
Recomendaría pasar un poco de tiempo con las mejores prácticas para los vectores de inicialización de CBC. Su uso incorrecto puede debilitar la seguridad general de AES. La breve explicación es:
- Los IV deben ser aleatorios y generados por un CSPRNG.
- Las IV no deben reutilizarse. Es decir, no cifre el texto sin formato “A” y el texto sin formato “B” con el mismo IV. Cada registro debe tener su propio IV.
- El IV no es un secreto como el key. Se puede almacenar en texto sin formato junto con el texto cifrado.
También tenga en cuenta que este consejo solo se aplica a AES-CBC. Si alguna vez investiga otros modos de AES, como GCM, esto no se aplica.
Digamos que dos usuarios tienen la contraseña “princesa”, y los codifica con el key “alguno-key”, ambos tendrán el mismo resultado cifrado:
| User | Encrypted password |
|------------|-----------------------|
| a | sN7vIFg= |
| b | sN7vIFg= |
Lo que significa que si alguien descubre usando un medio diferente que la contraseña real del usuario a es “princesa” y su contraseña encriptada es “sN7vIFg=”, entonces se puede considerar que cualquier usuario con la contraseña encriptada “sN7vIFg=” tiene la contraseña “princesa”. “.
Sin embargo, si utiliza un IV aleatorio para cada uno, será más difícil adivinar las contraseñas subyacentes si tiene acceso a los datos cifrados.
| User | Encrypted password | IV |
|------------|-----------------------|----------------|
| a | sN7vIFg= | h²ÓIF8]h%L |
| b | BjZAzrA= | VÂøíiøÚØò▓ |
Ahora, incluso si alguien tiene acceso a los datos anteriores, no puede darse cuenta de que los usuarios a y b tienen la misma contraseña.
Consulte también ¿Es “sal real” lo mismo que “vectores de inicialización”? .
Creo que tal vez mixed hasta “hash key” y “iv” (Dios sabe que lo hice cuando comencé crypto). hash key es exactamente lo que hiciste. Para iv, debe usar datos aleatorios diferentes cada vez que se realiza el cifrado con el mismo key. (mi experiencia: tuve que crear un controlador de sesión seguro pdo que encripta/descifra los datos de la sesión, así que terminé implementando AES-256-CBC usando la extensión openssl)
solo un pequeño consejo si alguien llega aquí.
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
no es la forma correcta de generar iv + no hay necesidad de secret_iv porque iv tiene que ser lo más aleatorio posible. No lo trate (ni lo entienda) de la misma manera que hashing.
Como tiene acceso a la extensión de openssl, existe una forma mejor/más segura de generar iv para el cifrado elegido, openssl también puede indicarle la longitud correcta de iv para el cifrado:
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('AES-256-CBC'));
Estará en formato binario, por lo que si lo necesita en hexadecimal, use bin2hex ($ iv). Si necesita almacenar el iv generado en mysql, lo almaceno en formato sin procesar (tipo de campo varbinary, binario también funciona).
Una cosa más. Tiene la etiqueta $options establecida en 0 tanto en openssl_encrypt como en _decrypt, lo que significa “si se establece en true devolverá como datos de salida sin procesar; de lo contrario, el valor de retorno está codificado en base64”.
Al final de la página puedes encontrar las explicaciones de otros usuarios, tú asimismo tienes la libertad de insertar el tuyo si dominas el tema.