OpenSSL 변경 사항

스트림 래퍼는 이제 기본적으로 피어 인증서와 호스트 이름을 사용할 때 확인합니다.


SSL/TLS

모든 암호화된 클라이언트 스트림은 이제 기본적으로 피어 확인을 활성화합니다. 기본적으로 OpenSSL의 기본 CA 번들을 사용하여 피어 인증서를 확인합니다. 배포자는 일반적으로 알려진 양호한 CA 번들을 사용하도록 OpenSSL을 구성하므로 대부분의 경우 유효한 SSL 인증서가 있는 서버와 통신하기 위해 변경할 필요가 없습니다.

기본 CA 번들은 openssl.cafile 또는 openssl.capath 구성 설정을 설정하여 전역적으로 재정의하거나 cafile 또는 capath 컨텍스트 옵션을 사용하여 요청별로 재정의할 수 있습니다.

일반적으로 권장되지는 않지만 verify_peer 컨텍스트 옵션을 false로 설정하여 요청에 대한 피어 인증서 확인을 비활성화하고 verify_peer_name 컨텍스트 옵션을 false로 설정하여 피어 이름 유효성 검사를 비활성화할 수 있습니다.


Certificate fingerprints

인증서 지문 추출 및 확인에 대한 지원이 추가되었습니다. X.509 인증서에서 지문을 추출하기 위해 openssl_x509_fingerprint()가 추가되었으며 두 가지 SSL 스트림 컨텍스트 옵션이 추가되었습니다. capture_peer_cert는 피어의 X.509 인증서를 캡처하고 peer_fingerprint는 피어의 인증서가 주어진 지문과 일치해야 한다고 주장합니다.


Default ciphers updated

PHP에서 사용하는 기본 암호는 » Mozilla 암호 권장 사항에 따라 더 안전한 목록으로 업데이트되었으며 익명 Diffie-Hellman 암호와 RC4라는 두 가지 추가 제외 항목이 있습니다.

이 목록은 새로운 OPENSSL_DEFAULT_STREAM_CIPHERS 상수를 통해 액세스할 수 있으며 (이전 PHP 버전에서와 같이) ciphers 컨텍스트 옵션을 설정하여 재정의할 수 있습니다.


Compression disabled by default

SSL/TLS 압축은 CRIME 공격을 완화하기 위해 기본적으로 비활성화되어 있습니다. PHP 5.4.13에는 압축을 비활성화할 수 있는 disable_compression 컨텍스트 옵션이 추가되었습니다. 이제 기본적으로 true로 설정됩니다(즉, 압축이 비활성화됨).


Allow servers to prefer their cipher order

Honor_cipher_order SSL 컨텍스트 옵션이 추가되어 암호화된 스트림 서버가 클라이언트의 암호보다 서버의 암호를 선호하여 BEAST 취약점을 완화할 수 있습니다.


Access the negotiated protocol and cipher

capture_session_meta SSL 컨텍스트 옵션이 true로 설정된 경우 암호화된 스트림에 대해 협상된 프로토콜 및 암호에 이제 stream_get_meta_data() 또는 stream_context_get_options()를 통해 액세스할 수 있습니다.

                  
<?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);
?>
                  
                

위의 예는 다음을 출력합니다.

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

New options for perfect forward secrecy in encrypted stream servers

암호화된 클라이언트 스트림은 일반적으로 서버에서 제어하므로 이미 완벽한 순방향 비밀성을 지원합니다. 완전 순방향 보안이 가능한 인증서를 사용하는 PHP 암호화 서버 스트림은 PFS를 활성화하기 위해 추가 작업을 수행할 필요가 없습니다. 그러나 PFS에 대한 더 많은 제어를 허용하고 발생할 수 있는 호환성 문제를 처리하기 위해 여러 가지 새로운 SSL 컨텍스트 옵션이 추가되었습니다.

    ecdh_curve
    이 옵션을 사용하면 ECDH 암호와 함께 사용할 특정 곡선을 선택할 수 있습니다. 지정하지 않으면 Prime256v1이 사용됩니다.
    dh_param
    다음 명령으로 생성된 것과 같은 Diffie-Hellman 키 교환을 위한 매개변수가 포함된 파일의 경로:
    openssl dhparam -out /path/to/my/certs/dh-2048.pem 2048
                        
    single_dh_use
    true로 설정하면 Diffie-Hellman 매개변수를 사용할 때 새 키 쌍이 생성되어 순방향 비밀성이 향상됩니다.
    single_ecdh_use
    true로 설정하면 ECDH 암호 제품군이 협상될 때 항상 새 키 쌍이 생성됩니다. 이것은 순방향 비밀성을 향상시킵니다.

SSL/TLS version selection

이제 crypto_method SSL 컨텍스트 옵션을 통해 또는 스트림 래퍼를 생성할 때 특정 전송을 지정하여(예: stream_socket_client() 또는 stream_socket_server() 호출) 특정 버전의 SSL 및 TLS를 선택할 수 있습니다.

crypto_method SSL 컨텍스트 옵션은 stream_socket_enable_crypto()의 crypto_type과 마찬가지로 허용된 프로토콜을 열거하는 비트마스크를 허용합니다.

Selected protocol versions and corresponding options

Protocol(s) Client flag Server flag Transport
Any TLS or SSL version STREAM_CRYPTO_METHOD_ANY_CLIENT STREAM_CRYPTO_METHOD_ANY_SERVER ssl://
Any TLS version 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

// Requiring TLS 1.0 or better when using file_get_contents():
$ctx = stream_context_create([
    'ssl' => [
        'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT,
    ],
]);
$html = file_get_contents('https://google.com/', false, $ctx);

// Requiring TLS 1.1 or 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);

// Connecting using the tlsv1.2:// stream socket transport.
$sock = stream_socket_client('tlsv1.2://google.com:443/');

?>
                  
                

openssl_get_cert_locations() added

openssl_get_cert_locations() 함수가 추가되었습니다. 이 함수는 CA 번들을 찾을 때 PHP가 검색할 기본 위치를 반환합니다.

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

위의 예는 다음을 출력합니다.

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) ""
}
                

SPKI support

서명된 공개 키 및 챌린지(SPKAC) 생성, 추출 및 확인에 대한 지원이 추가되었습니다. openssl_spki_new(), openssl_spki_verify(), openssl_spki_export_challenge()openssl_spki_export()가 추가되어 KeyGen HTML5 요소에서 생성된 SPKAC에서 내보내기 PEM 공개 키 및 관련 챌린지를 만들고 확인합니다.

    openssl_spki_new
    개인 키, 챌린지 문자열 및 해싱 알고리즘을 사용하여 새 SPKAC를 생성합니다.
                          
    <?php
    $pkey = openssl_pkey_new();
    openssl_pkey_export($pkey, 'secret passphrase');
    
    $spkac = openssl_spki_new($pkey, 'challenge string');
    ?>
                          
                        

    위의 예는 다음을 출력합니다.

    SPKAC=MIIBXjCByDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3L0IfUijj7+A8CPC8EmhcdNoe5fUAog7OrBdhn7EkxFButUp40P7+LiYiygYG1TmoI/a5EgsLU3s9twEz3hmgY9mYIqb/rb+SF8qlD/K6KVyUORC7Wlz1Df4L8O3DuRGzx6/+3jIW6cPBpfgH1sVuYS1vDBsP/gMMIxwTsKJ4P0CAwEAARYkYjViMzYxMTktNjY5YS00ZDljLWEyYzctMGZjNGFhMjVlMmE2MA0GCSqGSIb3DQEBAwUAA4GBAF7hu0ifzmjonhAak2FhhBRsKFDzXdKIkrWxVNe8e0bZzMrWOxFM/rqBgeH3/gtOUDRS5Fnzyq425UsTYbjfiKzxGeCYCQJb1KJ2V5Ij/mIJHZr53WYEXHQTNMGR8RPm7IxwVXVSHIgAfXsXZ9IXNbFbcaLRiSTr9/N4U+MXUWL7
                        
    openssl_spki_verify
    제공된 SPKAC를 확인합니다.
                          
    <?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
    제공된 SPKAC에서 관련 챌린지를 내보냅니다.
                          
    <?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;
    ?>
                          
                        

    위의 예는 다음을 출력합니다.

    challenge string
                        
    openssl_spki_export
    SPKAC에서 PEM 형식의 RSA 공개 키를 내보냅니다.
                          
    <?php
    $pkey = openssl_pkey_new();
    openssl_pkey_export($pkey, 'secret passphrase');
    
    $spkac = openssl_spki_new($pkey, 'challenge string');
    echo openssl_spki_export($spkac);
    ?>
                          
                        

    위의 예는 다음을 출력합니다.

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