## Cambios para OpenSSL en PHP 5.6.x

### Los manejadores de flujo ahora verifican por defecto los certificados de par y los nombres de host al usar SSL/TLS

Todos los flujos clientes cifrados activan ahora la verificación por pares por omisión. Por omisión, esto utilizará el CA OpenSSL por omisión para verificar el par de certificados. En la mayoría de los casos, no se necesita realizar ninguna modificación para comunicarse con servidores y certificados SSL válidos, sabiendo que los distribuidores configuran generalmente OpenSSL para utilizar los CA conocidos.

El CA por omisión puede ser sobrescrito a nivel global utilizando las opciones de configuración openssl.cafile o openssl.capath, o mediante una solicitud básica utilizando las opciones de contexto `cafile` o `capath`.

Aunque no se recomienda en general, es posible desactivar la verificación de certificados por pares para una solicitud definiendo la opción de contexto `verify_peer` a `false`, y para desactivar la validación del nombre de los pares, configurando la opción de contexto `verify_peer_name` a `false`.

### Huellas digitales de certificado

Se ha añadido soporte para extraer y verificar las huellas digitales de los certificados. openssl_x509_fingerprint() se ha añadido para extraer una huella digital de un certificado X.509 y dos opciones de contexto de flujo SSL han sido añadidas: `capture_peer_cert` para capturar el certificado X.509 del par y `peer_fingerprint` para asegurar que el certificado del par debe coincidir con la huella digital dada.

### Cifrados por defecto actualizados

Los cifrados por defecto usados por PHP han sido actualizados a una lista más segura basada en las » recomendaciones de cifrado de Mozilla, con dos exclusiones adicionales: cifrados Diffie-Hellman anónimos y RC4.

Esta lista es accesible a través de la nueva constante `OPENSSL_DEFAULT_STREAM_CIPHERS` y puede ser reemplazada (como en versiones anteriores de PHP) definiendo la opción de contexto `cifrados`.

### Compresión desactivada por defecto

La compresión SSL/TLS ha sido desactivada por defecto para mitigar el ataque CRIME. PHP 5.4.13 añadió una opción de contexto `disable_compression` para permitir que la compresión sea desactivada: ahora está establecida en `true` (es decir, la compresión está desactivada) por defecto.

### Permitir a los servidores preferir su orden de cifrado

La opción de contexto SSL `honor_cipher_order` ha sido añadida para permitir a los servidores de flujos cifrados mitigar las vulnerabilidades de BEAST prefiriendo los cifrados del servidor sobre el cliente.

### Acceder al protocolo negociado y al cifrado

El protocolo y el cifrado que han sido negociados para un flujo cifrado ahora pueden ser accedidos a través de stream_get_meta_data() o stream_context_get_options() cuando la opción de contexto SSL `capture_session_meta` está establecida en `true`.

    <?php
    $ctx = stream_context_create(['ssl' => [
        'capture_session_meta' => TRUE
    ]]);

    $html = file_get_contents('https://google.com/', FALSE, $ctx);
    $meta = stream_context_get_options($ctx)['ssl']['session_meta'];
    var_dump($meta);
    ?>

El ejemplo anterior mostrará:

    array(4) {
      ["protocol"]=>
      string(5) "TLSv1"
      ["cipher_name"]=>
      string(20) "ECDHE-RSA-AES128-SHA"
      ["cipher_bits"]=>
      int(128)
      ["cipher_version"]=>
      string(11) "TLSv1/SSLv3"
    }

### Nuevas opciones para la confidencialidad persistente en servidores de flujos cifrados

Los flujos de clientes cifrados ya soportan la confidencialidad persistente, ya que generalmente es controlado por el servidor. Los flujos de servidores cifrados en PHP usando certificados capaces de confidencialidad persistente no necesitan tomar medidas adicionales para habilitar PFS; sin embargo, se han añadido varias nuevas opciones de contexto SSL para permitir un mayor control sobre PFS y manejar problemas de compatibilidad que puedan surgir.

`ecdh_curve`

  Esta opción permite seleccionar una curva específica para usar con los cifrados ECDH. Si no se especifica, se usará `prime256v1`.

`dh_param`

  Ruta a un archivo que contiene parámetros para el intercambio de claves Diffie-Hellman, como el creado por el siguiente comando:

      openssl dhparam -out /path/to/my/certs/dh-2048.pem 2048

`single_dh_use`

  Si se establece en `true`, se creará un nuevo par de claves al usar los parámetros Diffie-Hellman, mejorando así la confidencialidad persistente.

`single_ecdh_use`

  Si se establece en `true`, siempre se generará un nuevo par de claves al negociar las suites de cifrado ECDH. Esto mejora la confidencialidad persistente.

### Selección de la versión SSL/TLS

Ahora es posible seleccionar versiones específicas de SSL y TLS a través de la opción de contexto SSL `crypto_method` o especificando un transporte específico al crear un manejador de flujo (por ejemplo, llamando a stream_socket_client() o stream_socket_server()).

La opción de contexto SSL `crypto_method` acepta una máscara de bits enumerando los protocolos que están permitidos, como lo hace el `crypto_type` de stream_socket_enable_crypto().

Versiones de protocolo seleccionadas y opciones correspondientes
Protocolo(s) | Bandera cliente | Bandera servidor | Transporte
--- | --- | --- | ---
Cualquier versión TLS o SSL | `STREAM_CRYPTO_METHOD_ANY_CLIENT` | `STREAM_CRYPTO_METHOD_ANY_SERVER` | `ssl://`
Cualquier versión TLS | `STREAM_CRYPTO_METHOD_TLS_CLIENT` | `STREAM_CRYPTO_METHOD_TLS_SERVER` | `tls://`
TLS 1.0 | `STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT` | `STREAM_CRYPTO_METHOD_TLSv1_0_SERVER` | `tlsv1.0://`
TLS 1.1 | `STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT` | `STREAM_CRYPTO_METHOD_TLSv1_1_SERVER` | `tlsv1.1://`
TLS 1.2 | `STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT` | `STREAM_CRYPTO_METHOD_TLSv1_2_SERVER` | `tlsv1.2://`
SSL 3 | `STREAM_CRYPTO_METHOD_SSLv3_CLIENT` | `STREAM_CRYPTO_METHOD_SSLv3_SERVER` | `sslv3://`

    <?php

    // Requiriendo TLS 1.0 o mejor al usar file_get_contents():
    $ctx = stream_context_create([
        'ssl' => [
            'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT,
        ],
    ]);
    $html = file_get_contents('https://google.com/', false, $ctx);

    // Requiriendo TLS 1.1 o 1.2:
    $ctx = stream_context_create([
        'ssl' => [
            'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT |
                               STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,
        ],
    ]);
    $html = file_get_contents('https://google.com/', false, $ctx);

    // Conexión usando el transporte de socket tlsv1.2://.
    $sock = stream_socket_client('tlsv1.2://google.com:443/');

    ?>

### Adición de openssl_get_cert_locations()

Se ha añadido la función openssl_get_cert_locations(): devuelve las ubicaciones por defecto donde PHP buscará al buscar paquetes CA.

    <?php
    var_dump(openssl_get_cert_locations());
    ?>

El ejemplo anterior mostrará:

    array(8) {
      ["default_cert_file"]=>
      string(21) "/etc/pki/tls/cert.pem"
      ["default_cert_file_env"]=>
      string(13) "SSL_CERT_FILE"
      ["default_cert_dir"]=>
      string(18) "/etc/pki/tls/certs"
      ["default_cert_dir_env"]=>
      string(12) "SSL_CERT_DIR"
      ["default_private_dir"]=>
      string(20) "/etc/pki/tls/private"
      ["default_default_cert_area"]=>
      string(12) "/etc/pki/tls"
      ["ini_cafile"]=>
      string(0) ""
      ["ini_capath"]=>
      string(0) ""
    }

### Soporte SPKI

Se ha añadido soporte para generar, extraer y verificar claves y desafíos públicos firmados (SPKAC). openssl_spki_new(), openssl_spki_verify(), openssl_spki_export_challenge() y openssl_spki_export() han sido añadidas para crear, verificar la clave pública PEM de exportación y el desafío asociado de SPKAC generados a partir de un elemento HTML5 `KeyGen`.

`openssl_spki_new`

  Genera un nuevo SPKAC usando la clave privada, string de desafío y el algoritmo de hashing.

      <?php
      $pkey = openssl_pkey_new();
      openssl_pkey_export($pkey, 'secret passphrase');

      $spkac = openssl_spki_new($pkey, 'challenge string');
      ?>

  El ejemplo anterior mostrará:

      SPKAC=MIIBXjCByDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3L0IfUijj7+A8CPC8EmhcdNoe5fUAog7OrBdhn7EkxFButUp40P7+LiYiygYG1TmoI/a5EgsLU3s9twEz3hmgY9mYIqb/rb+SF8qlD/K6KVyUORC7Wlz1Df4L8O3DuRGzx6/+3jIW6cPBpfgH1sVuYS1vDBsP/gMMIxwTsKJ4P0CAwEAARYkYjViMzYxMTktNjY5YS00ZDljLWEyYzctMGZjNGFhMjVlMmE2MA0GCSqGSIb3DQEBAwUAA4GBAF7hu0ifzmjonhAak2FhhBRsKFDzXdKIkrWxVNe8e0bZzMrWOxFM/rqBgeH3/gtOUDRS5Fnzyq425UsTYbjfiKzxGeCYCQJb1KJ2V5Ij/mIJHZr53WYEXHQTNMGR8RPm7IxwVXVSHIgAfXsXZ9IXNbFbcaLRiSTr9/N4U+MXUWL7

`openssl_spki_verify`

  Verifica el SPKAC proporcionado.

      <?php
      $pkey = openssl_pkey_new();
      openssl_pkey_export($pkey, 'secret passphrase');

      $spkac = openssl_spki_new($pkey, 'challenge string');
      var_dump(openssl_spki_verify($spkac));
      ?>

`openssl_spki_export_challenge`

  Exporta el desafío asociado al SPKAC proporcionado.

      <?php
      $pkey = openssl_pkey_new();
      openssl_pkey_export($pkey, 'secret passphrase');

      $spkac = openssl_spki_new($pkey, 'challenge string');
      $challenge = openssl_spki_export_challenge($spkac);
      echo $challenge;
      ?>

  El ejemplo anterior mostrará:

      challenge string

`openssl_spki_export`

  Exporta la clave pública RSA en formato PEM del SPKAC.

      <?php
      $pkey = openssl_pkey_new();
      openssl_pkey_export($pkey, 'secret passphrase');

      $spkac = openssl_spki_new($pkey, 'challenge string');
      echo openssl_spki_export($spkac);
      ?>

  El ejemplo anterior mostrará:

      -----BEGIN PUBLIC KEY-----
      MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcvQh9SKOPv4DwI8LwSaFx02h7
      l9QCiDs6sF2GfsSTEUG61SnjQ/v4uJiLKBgbVOagj9rkSCwtTez23ATPeGaBj2Zg
      ipv+tv5IXyqUP8ropXJQ5ELtbXPUN/gvw7cO5EbPHr/7eMhbpw8Gl+AfWxW5hLW8
      MGw/+AwwjHBOwong/QIDAQAB
      -----END PUBLIC KEY-----

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open