tipos password_hash password encriptar encriptada encriptacion ejemplo desencriptar contraseña con php security encryption cryptography encryption-symmetric

password_hash - Encriptación bidireccional más simple usando PHP



password_hash php ejemplo (5)

Aquí hay una implementación simple pero segura:

  • Encriptación AES-256 en modo CBC
  • PBKDF2 para crear una clave de cifrado con una contraseña de texto sin formato
  • HMAC para autenticar el mensaje cifrado.

El código y los ejemplos están aquí: https://stackoverflow.com/a/19445173/1387163

¿Cuál es la forma más simple de hacer un cifrado bidireccional en las instalaciones comunes de PHP?

Necesito poder encriptar datos con una clave de cadena y usar la misma clave para descifrar en el otro extremo.

La seguridad no es tan preocupante como la portabilidad del código, por lo que me gustaría poder mantener las cosas lo más simples posible. Actualmente, estoy usando una implementación RC4, pero si puedo encontrar algo con soporte nativo me imagino que puedo guardar un montón de código innecesario.


Formas nativas super simples y simples para pseudo encriptar / descifrar, sin claves ni bibliotecas externas:

Estas son las formas más simples de hacer un cifrado bidireccional (falso / pseudo) en las instalaciones comunes de PHP.


Use mcrypt_encrypt() y mcrypt_decrypt() con los parámetros correspondientes. Muy fácil y sencillo, y utiliza un paquete de cifrado probado en batalla.

EDITAR

5 años y 4 meses después de esta respuesta, la extensión mcrypt está ahora en proceso de desaprobación y eventual eliminación de PHP.



Importante : a menos que tenga un caso de uso muy particular, no cifre las contraseñas , use un algoritmo de hashing de contraseña. Cuando alguien dice que encriptan sus contraseñas en una aplicación del lado del servidor, o no están informados o están describiendo un diseño de sistema peligroso. El almacenamiento seguro de contraseñas es un problema totalmente separado del cifrado.

Ser informado. Diseño de sistemas seguros

Cifrado de datos portátil en PHP

Si está utilizando PHP 5.4 o posterior y no desea escribir un módulo de criptografía, recomiendo usar una biblioteca existente que proporcione cifrado autenticado . La biblioteca que he vinculado solo se basa en lo que PHP proporciona y está bajo revisión periódica por un puñado de investigadores de seguridad. (Yo mismo incluido)

Si sus objetivos de portabilidad no impiden que se requieran extensiones PECL, se recomienda mucho libsodium sobre cualquier cosa que usted o yo podamos escribir en PHP.

Actualización (2016-06-12): ahora puede usar sodium_compat y usar las mismas ofertas de crypto libsodium sin instalar extensiones PECL.

Si quieres probar suerte en ingeniería de criptografía, sigue leyendo.

En primer lugar, debe tomarse el tiempo para aprender sobre los peligros del cifrado no autenticado y el Principio de Doce Criptográfico .

  • Los datos cifrados todavía pueden ser manipulados por un usuario malintencionado.
  • La autenticación de los datos cifrados evita la manipulación.
  • Autenticar los datos no encriptados no evita la manipulación.

Cifrado y descifrado

El cifrado en PHP es realmente simple (vamos a usar openssl_encrypt() y openssl_decrypt() una vez que haya tomado algunas decisiones sobre cómo cifrar su información. Consulte openssl_get_cipher_methods() para obtener una lista de los métodos compatibles en su sistema. la opción es AES en modo CTR :

  • aes-128-ctr
  • aes-192-ctr
  • aes-256-ctr

Actualmente, no hay motivos para creer que el tamaño de la clave AES sea ​​un problema importante (más grande probablemente no sea mejor, debido a la mala programación de claves en el modo de 256 bits).

Nota: No estamos usando mcrypt porque es abandonware y tiene errores no reparados que pueden afectar la seguridad. Debido a estas razones, animo a otros desarrolladores de PHP a evitarlo también.

Contenedor de cifrado / descifrado simple usando OpenSSL

class UnsafeCrypto { const METHOD = ''aes-256-ctr''; /** * Encrypts (but does not authenticate) a message * * @param string $message - plaintext message * @param string $key - encryption key (raw binary expected) * @param boolean $encode - set to TRUE to return a base64-encoded * @return string (raw binary) */ public static function encrypt($message, $key, $encode = false) { $nonceSize = openssl_cipher_iv_length(self::METHOD); $nonce = openssl_random_pseudo_bytes($nonceSize); $ciphertext = openssl_encrypt( $message, self::METHOD, $key, OPENSSL_RAW_DATA, $nonce ); // Now let''s pack the IV and the ciphertext together // Naively, we can just concatenate if ($encode) { return base64_encode($nonce.$ciphertext); } return $nonce.$ciphertext; } /** * Decrypts (but does not verify) a message * * @param string $message - ciphertext message * @param string $key - encryption key (raw binary expected) * @param boolean $encoded - are we expecting an encoded string? * @return string */ public static function decrypt($message, $key, $encoded = false) { if ($encoded) { $message = base64_decode($message, true); if ($message === false) { throw new Exception(''Encryption failure''); } } $nonceSize = openssl_cipher_iv_length(self::METHOD); $nonce = mb_substr($message, 0, $nonceSize, ''8bit''); $ciphertext = mb_substr($message, $nonceSize, null, ''8bit''); $plaintext = openssl_decrypt( $ciphertext, self::METHOD, $key, OPENSSL_RAW_DATA, $nonce ); return $plaintext; } }

Ejemplo de uso

$message = ''Ready your ammunition; we attack at dawn.''; $key = hex2bin(''000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f''); $encrypted = UnsafeCrypto::encrypt($message, $key); $decrypted = UnsafeCrypto::decrypt($encrypted, $key); var_dump($encrypted, $decrypted);

Demostración : https://3v4l.org/jl7qR

La biblioteca de cifrado simple anterior todavía no es segura de usar. Necesitamos autenticar los textos cifrados y verificarlos antes de descifrarlos .

Nota : De forma predeterminada, UnsafeCrypto::encrypt() devolverá una cadena binaria en bruto. Llámelo así si necesita almacenarlo en un formato binario seguro (codificado en base64):

$message = ''Ready your ammunition; we attack at dawn.''; $key = hex2bin(''000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f''); $encrypted = UnsafeCrypto::encrypt($message, $key, true); $decrypted = UnsafeCrypto::decrypt($encrypted, $key, true); var_dump($encrypted, $decrypted);

Demostración : http://3v4l.org/f5K93

Contenedor de autenticación simple

class SaferCrypto extends UnsafeCrypto { const HASH_ALGO = ''sha256''; /** * Encrypts then MACs a message * * @param string $message - plaintext message * @param string $key - encryption key (raw binary expected) * @param boolean $encode - set to TRUE to return a base64-encoded string * @return string (raw binary) */ public static function encrypt($message, $key, $encode = false) { list($encKey, $authKey) = self::splitKeys($key); // Pass to UnsafeCrypto::encrypt $ciphertext = parent::encrypt($message, $encKey); // Calculate a MAC of the IV and ciphertext $mac = hash_hmac(self::HASH_ALGO, $ciphertext, $authKey, true); if ($encode) { return base64_encode($mac.$ciphertext); } // Prepend MAC to the ciphertext and return to caller return $mac.$ciphertext; } /** * Decrypts a message (after verifying integrity) * * @param string $message - ciphertext message * @param string $key - encryption key (raw binary expected) * @param boolean $encoded - are we expecting an encoded string? * @return string (raw binary) */ public static function decrypt($message, $key, $encoded = false) { list($encKey, $authKey) = self::splitKeys($key); if ($encoded) { $message = base64_decode($message, true); if ($message === false) { throw new Exception(''Encryption failure''); } } // Hash Size -- in case HASH_ALGO is changed $hs = mb_strlen(hash(self::HASH_ALGO, '''', true), ''8bit''); $mac = mb_substr($message, 0, $hs, ''8bit''); $ciphertext = mb_substr($message, $hs, null, ''8bit''); $calculated = hash_hmac( self::HASH_ALGO, $ciphertext, $authKey, true ); if (!self::hashEquals($mac, $calculated)) { throw new Exception(''Encryption failure''); } // Pass to UnsafeCrypto::decrypt $plaintext = parent::decrypt($ciphertext, $encKey); return $plaintext; } /** * Splits a key into two separate keys; one for encryption * and the other for authenticaiton * * @param string $masterKey (raw binary) * @return array (two raw binary strings) */ protected static function splitKeys($masterKey) { // You really want to implement HKDF here instead! return [ hash_hmac(self::HASH_ALGO, ''ENCRYPTION'', $masterKey, true), hash_hmac(self::HASH_ALGO, ''AUTHENTICATION'', $masterKey, true) ]; } /** * Compare two strings without leaking timing information * * @param string $a * @param string $b * @ref https://paragonie.com/b/WS1DLx6BnpsdaVQW * @return boolean */ protected static function hashEquals($a, $b) { if (function_exists(''hash_equals'')) { return hash_equals($a, $b); } $nonce = openssl_random_pseudo_bytes(32); return hash_hmac(self::HASH_ALGO, $a, $nonce) === hash_hmac(self::HASH_ALGO, $b, $nonce); } }

Ejemplo de uso

$message = ''Ready your ammunition; we attack at dawn.''; $key = hex2bin(''000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f''); $encrypted = SaferCrypto::encrypt($message, $key); $decrypted = SaferCrypto::decrypt($encrypted, $key); var_dump($encrypted, $decrypted);

Demostraciones : binario sin procesar , base64-encoded

Si alguien desea usar esta biblioteca SaferCrypto en un entorno de producción, o su propia implementación de los mismos conceptos, le recomiendo que se comunique con sus criptógrafos residentes para obtener una segunda opinión antes de hacerlo. Podrán informarle acerca de errores de los que ni siquiera soy consciente.

Será mucho mejor utilizar una biblioteca de criptografía de buena reputación .