Mudanças do OpenSSL no PHP 5.6.x
Empacotadores de fluxo agora verificam nomes e certificados de servidor por padrão ao usar SSL/TLS
Todos os streams criptografados de cliente agora permitem a verificação de mesmo nível por padrão. Por padrão, será usada a coleção de CAs padrão do OpenSSL para verificar o certificado de mesmo nível. Na maioria dos casos, nenhuma alteração precisará ser feita para se comunicar com servidores com certificados SSL válidos, pois as distribuições geralmente configuram o OpenSSL com coleções de CAs bem conhecidos.
A coleção de CAs padrão pode ser substituída globalmente definindo
a configuração openssl.cafile ou openssl.capath, ou
por requisição usando as opções de contexto
cafile
ou
capath
.
Embora em geral não seja recomendado, é possível desabilitar a verificação
de certificado de mesmo nível para uma requisição definindo a opção de contexto
verify_peer
para false
e é possível desabilitar a verificação de nome de mesmo nível definindo a opção de contexto
verify_peer_name
para false
.
Impressões digitais de certificado
Foi adicionado suporte para extrari e verificar impressões digitais de
certificado. openssl_x509_fingerprint() foi adicionada para
extrair uma impressão digital de um certificado X.509 certificate, e duas
opções de contexto de fluxo SSL foram
adicionadas: capture_peer_cert
para capturar o certificado X.509
do servidor, e peer_fingerprint
para certificar que o
certificado do servidor deve corresponder à impressão digital informada.
Cifras padrões atualizadas
As cifras padrões usadas pelo PHP foram atualizadas para uma lista mais segura com base nas » Recomendações de crifra Mozilla, com duas novas exclusões: cifras anônimas Diffie-Hellman, e RC4.
Esta lista pode ser acessada através da nova constante
OPENSSL_DEFAULT_STREAM_CIPHERS
, e pode ser
substituída (como em versões anteriores do PHP) configurando-se as opções
de contexto
ciphers
.
Compressão desabilitada por padrão
Compressão SSL/TLS foi desabilitada por padrão para mitigar o ataque
CRIME. O PHP 5.4.13 adicionou uma opção de contexto
disable_compression
para permitir que a compressão seja desabilitada: ela agora está definida para
true
(isto é, compressão desabilitada) por padrão.
Permite que servidores definam sua própria ordem de cifras de preferência
A opção de contexto SSL honor_cipher_order
foi adicionada
para permitir que servidores de fluxo criptografado mitiguem vulnerabilidades BEAST
definindo as cifras do servidor e não as do cliente.
Acesso ao protocolo e à cifra negociados
O protocolo e a cifra que foram negociados para um fluxo criptografado
agora podem ser acessados por stream_get_meta_data() ou
stream_context_get_options() quando a opção de contexto SSL
capture_session_meta
for definida para
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);
?>
O exemplo acima produzirá:
array(4) { ["protocol"]=> string(5) "TLSv1" ["cipher_name"]=> string(20) "ECDHE-RSA-AES128-SHA" ["cipher_bits"]=> int(128) ["cipher_version"]=> string(11) "TLSv1/SSLv3" }
Novas opções para sigilo de encaminhamento perfeito em servidores de fluxo criptografados
Os fluxos criptografados de clientes já suportam sigilo de encaminhamento perfeito, pois geralmente são controlados pelo servidor. Fluxos criptografados de servidor no PHP usando certificados capazes de sigilo de encaminhamento perfeito não precisam tomar nenhuma ação adicional para habilitar o SEP; entretanto um número de opções de contexto SSL foi adicionado para permitir maior controle sobre o SEP e lidar com problemas de compatibilidade que possam aparecer.
ecdh_curve
-
Esta opção permite a seleção de uma curva específica para uso com cifras ECDH. Se não especificada,
prime256v1
será usada. dh_param
-
Um caminho para um arquivo contendo parâmetros para a troca de chaves Diffie-Hellman key, como as criadas pelo comando:
openssl dhparam -out /caminho/para/meus/certificados/dh-2048.pem 2048
single_dh_use
-
Se definida para
true
, um novo par de chaves será criado usando parâmetros Diffie-Hellman, desta forma melhorando o sigilo de encaminhamento. single_ecdh_use
-
Se definida para
true
, um novo par de chaves será sempre gerado quando conjuntos de cifras ECDH forem negociadas. Isto melhora o sigilo de encaminhamento.
Seleção de versão SSL/TLS
Agora é possível selecionar versões específicas de SSL e TLS através da
opçõa de contexto crypto_method
ou pela especificação de
um transporte específico ao criar um empacotador de fluxo (por exemplo, chamando-se
stream_socket_client() ou
stream_socket_server()).
A opção de contexto crypto_method
aceita uma máscara de bits
enumerando os protocolos permitidos, da mesma forma que a opção
crypto_type
da função
stream_socket_enable_crypto().
Protocolo(s) | Opção do Cliente | Opção do Servidor | Transporte |
---|---|---|---|
Qualquer versão TLS ou SSL | STREAM_CRYPTO_METHOD_ANY_CLIENT |
STREAM_CRYPTO_METHOD_ANY_SERVER |
ssl:// |
Qualquer versão 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
// Requisitando TLS 1.0 ou melhor ao 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);
// Requisitando TLS 1.1 ou 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);
// Conectando com uso de transporte de fluxo tlsv1.2://.
$sock = stream_socket_client('tlsv1.2://google.com:443/');
?>
Adicionada a função openssl_get_cert_locations()
A função openssl_get_cert_locations() foi adicionada: ela retorna as localizações padrões onde o PHP irá pesquisar por pacotes de certificados CA.
<?php
var_dump(openssl_get_cert_locations());
?>
O exemplo acima produzirá:
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) "" }
Suporte a SPKI
Foi adicionado suporte para geração, extração e verificação de chaves públicas assinadas
e desafios (SPKAC em inglês). openssl_spki_new(),
openssl_spki_verify(),
openssl_spki_export_challenge() e
openssl_spki_export() foram adicionadas para criar, verificar,
exportar chaves públicas PEM e desafio associado a partir de um
SPKAC gerado por um elemento KeyGen
de HTML5.
openssl_spki_new
-
Gera uma novo SPKAC usando chave privada, string de desafio e algoritmo de hash.
<?php $pkey = openssl_pkey_new(); openssl_pkey_export($pkey, 'secret passphrase'); $spkac = openssl_spki_new($pkey, 'challenge string'); ?>
O exemplo acima produzirá:
SPKAC=MIIBXjCByDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3L0IfUijj7+A8CPC8EmhcdNoe5fUAog7OrBdhn7EkxFButUp40P7+LiYiygYG1TmoI/a5EgsLU3s9twEz3hmgY9mYIqb/rb+SF8qlD/K6KVyUORC7Wlz1Df4L8O3DuRGzx6/+3jIW6cPBpfgH1sVuYS1vDBsP/gMMIxwTsKJ4P0CAwEAARYkYjViMzYxMTktNjY5YS00ZDljLWEyYzctMGZjNGFhMjVlMmE2MA0GCSqGSIb3DQEBAwUAA4GBAF7hu0ifzmjonhAak2FhhBRsKFDzXdKIkrWxVNe8e0bZzMrWOxFM/rqBgeH3/gtOUDRS5Fnzyq425UsTYbjfiKzxGeCYCQJb1KJ2V5Ij/mIJHZr53WYEXHQTNMGR8RPm7IxwVXVSHIgAfXsXZ9IXNbFbcaLRiSTr9/N4U+MXUWL7
openssl_spki_verify
-
Verifica o SPKAC informado.
<?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 o desafio associado a partir do SPKAC fornecido.
<?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; ?>
O exemplo acima produzirá:
challenge string
openssl_spki_export
-
Exporta chave pública RSA em formato PEM, a partir do SPKAC.
<?php $pkey = openssl_pkey_new(); openssl_pkey_export($pkey, 'secret passphrase'); $spkac = openssl_spki_new($pkey, 'challenge string'); echo openssl_spki_export($spkac); ?>
O exemplo acima produzirá:
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcvQh9SKOPv4DwI8LwSaFx02h7 l9QCiDs6sF2GfsSTEUG61SnjQ/v4uJiLKBgbVOagj9rkSCwtTez23ATPeGaBj2Zg ipv+tv5IXyqUP8ropXJQ5ELtbXPUN/gvw7cO5EbPHr/7eMhbpw8Gl+AfWxW5hLW8 MGw/+AwwjHBOwong/QIDAQAB -----END PUBLIC KEY-----