Опции SSL-контекста — Список опций SSL-контекста
Опции контекста для протоколов ssl:// и tls://.
peer_name
string
Имя узла. Если значение параметра не задали, имя подставляется на основе имени хоста, который использовался при открытии потока.
verify_peer
bool
Требовать проверки SSL-сертификата.
По умолчанию true .
verify_peer_name
bool
Требовать проверки имени узла.
По умолчанию true .
allow_self_signed
bool
Разрешить самоподписанные сертификаты. Требуется
опция verify_peer.
По умолчанию false
cafile
string
Расположение файла центра сертификации в локальной файловой системе,
который следует использовать с опцией контекста verify_peer
для проверки подлинности удалённого узла.
capath
string
Если опцию cafile не определили или функция не смогла найти сертификат,
выполняется поиск в директории, которую указали в опции capath.
Путь capath должен указывать на корректную директорию, которая содержит сертификаты, имена которых —
хеш от поля subject, указанного в сертификате.
local_cert
string
Путь к локальному сертификату в файловой системе. Требуется файл, который закодировали в формате PEM,
который содержит ваш сертификат и закрытый ключ.
Файл дополнительно может содержать открытый ключ эмитента.
Закрытый ключ также может содержаться в отдельном файле, который задали опцией local_pk.
local_pk
string
Путь к локальному файлу с приватным ключом в случае отдельных
файлов сертификата (local_cert) и приватного ключа.
passphrase
string
Идентификационная фраза, с которой закодировали ваш файл local_cert.
verify_depth
int
Прервать, если цепочка сертификата слишком длинная.
По умолчанию проверка отсутствует.
ciphers
string
Устанавливает список доступных алгоритмов шифрования. Формат этой строки описывает страница » шифры(1).
По умолчанию принимает значение DEFAULT.
capture_peer_cert
bool
Если для опции установили значение true , будет создана опция контекста peer_certificate,
которая содержит сертификат удалённого узла.
capture_peer_cert_chain
bool
Если для опции установили значение true , будет создана опция контекста peer_certificate_chain,
которая содержит цепочку сертификатов.
SNI_enabled
bool
Если для опции установили значение true , включится индикация имени сервера. Включение SNI
разрешает использовать разные сертификаты на одном IP-адресе.
disable_compression
bool
Отключает TLS-сжатие, что помогает предотвратить атаки типа CRIME.
peer_fingerprint
string | array
Прерваться, если дайджест сообщения не совпадает с указанным хешем.
Если указали строку (string ), её длина определяет, какой алгоритм хеширования будет использоваться: «md5» (32) или «sha1» (40).
Если указали массив (array ), ключи определяют алгоритм хеширования, а каждое соответствующее значение представляет собой требуемым хешем.
security_level
int
Устанавливает уровень безопасности. Если не указали, используется стандартный уровень безопасности, указанный в библиотеке. Уровни безопасности описывает страница » SSL_CTX_get_security_level(3).
Доступна с PHP 7.2.0 и OpenSSL 1.1.0.
| Версия | Описание |
|---|---|
| 7.2.0 |
Добавили опцию security_level. Требуется OpenSSL >= 1.1.0.
|
Замечание: Поскольку
ssl://— нижележащий транспортный протокол для обёртокhttps://иftps://, любые опции контекста, которые применяются к транспортуssl://, будут также применяться к обёрткамhttps://иftps://.
Замечание: Чтобы указание имени сервера (SNI, Server Name Indication) было доступно, требуется скомпилировать PHP с OpenSSL 0.9.8j или более поздней. Чтобы определить, поддерживается ли SNI, указывают константу
OPENSSL_TLSEXT_SERVER_NAME.
Enable SNI (Server Name Indication):
PEM must be contains certificate and private key.
<?php
$context = stream_context_create([
'ssl' => [
'SNI_enabled' => true,
'SNI_server_certs' => [
'host1.com' => '/path/host1.com.pem',
'host2.com' => '/path/host2.com.pem',
],
]
]);
?>There is also a crypto_type context. In older versions this was crypto_method. This is referenced on http://php.net/manual/en/function.stream-socket-enable-crypto.php i usually download root CA certificate from https://curl.haxx.se/docs/caextract.html then put it as 'cafile' and it work almost all of the time.
the only problem i'v ever found is when the server does not properly sending intermediete CA certificate, then, you must add it manually to the file.I am unable to load a PEM that was generated with the stunnel tools. However, I am able to use PHP calls to generate a working PEM that is recognized both by stunnel and php, as outlined here:
http://www.devdungeon.com/content/how-use-ssl-sockets-php
This code fragment is now working for me, and with stunnel verify=4, both sides confirm the fingerprint. Oddly, if "tls://" is set below, then TLSv1 is forced, but using "ssl://" allows TLSv1.2:
$stream_context = stream_context_create([ 'ssl' => [
'local_cert' => '/path/to/key.pem',
'peer_fingerprint' => openssl_x509_fingerprint(file_get_contents('/path/to/key.crt')),
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
'verify_depth' => 0 ]]);
$fp = stream_socket_client('ssl://ssl.server.com:12345',
$errno, $errstr, 30, STREAM_CLIENT_CONNECT, $stream_context);
fwrite($fp, "foo bar\n");
while($line = fgets($fp, 8192)) echo $line;CN_match works contrary to intuitive thinking. I came across this when I was developing SSL server implemented in PHP. I stated (in code):
- do not allow self signed certs (works)
- verify peer certs against CA cert (works)
- verify the client's CN against CN_match (does not work), like this:
stream_context_set_option($context, 'ssl', 'CN_match', '*.example.org');
I presumed this would match any client with CN below .example.org domain.
Unfortunately this is NOT the case. The option above does not do that.
What it really does is this:
- it takes client's CN and compares it to CN_match
- IF CLIENT's CN CONTAINS AN ASTERISK like *.example.org, then it is matched against CN_match in wildcard matching fashion
Examples to illustrate behaviour:
(CNM = server's CN_match)
(CCN = client's CN)
- CNM=host.example.org, CCN=host.example.org ---> OK
- CNM=host.example.org, CCN=*.example.org ---> OK
- CNM=.example.org, CCN=*.example.org ---> OK
- CNM=example.org, CCN=*.example.org ---> ERROR
- CNM=*.example.org, CCN=host.example.org ---> ERROR
- CNM=*.example.org, CCN=*.example.org ---> OK
According to PHP sources I believe that the same applies if you are trying to act as Client and the server contains a wildcard certificate. If you set CN_match to myserver.example.org and server presents itself with *.example.org, the connection is allowed.
Everything above applies to PHP version 5.2.12.
I will supply a patch to support CN_match starting with asterisk.I used this for Apple Push Notification Service.
Passed in a local certificate filename `cert.pem` trough local_cert option.
Worked fine, when invoked the script directly.
But when I included/required the script from a different location, it stopped working, without any explicit error message.
Resolved by passed in the full path for the file `<FullPathTo>cert.pem`.recommended use "ssl://" transport.
in php 5.5 ~ 7.1
ssl:// transport = ssl_v2|ssl_v3|tls_v1.0|tls_v1.1|tls_v1.2
tls:// transport = tls_v1.0
after 7.2 ssl:// and tls:// transports is same
php 7.2 ~ 7.3 = tls_v1.0|tls_v1.1|tls_v1.2
php 7.4 ~ 8.1 = tls_v1.0|tls_v1.1|tls_v1.2|tls_v1.3If you want to validate the server against a local certificate, which you already saved, to further validate the target server, you have to use a fullchain.pem. Then the verify_peer option will work. So just get the server certificate, and search the root CA's pem's and copy everything into a single file. For example:
My certificate has the "GeoTrust TLS RSA CA G1" certificate in the chain, so you google that string. Go to the official digicert Geotrust page and download the "GeoTrustTLSRSACAG1.crt" certificate. Then you can use the following command to convert it into the pem format:
openssl x509 -inform DER -in GeoTrustTLSRSACAG1.crt -out GeoTrustTLSRSACAG1.crt.pem -outform PEMIt appears that "allow_self_signed" does not and cannot apply to the local_cert option.
The stunnel verify=4 option, which verifies but ignores a CA, has no analog in these settings, which is unfortunate.
Even more perplexingly, while the "openssl verify -CAfile" is successful, PHP appears unable to use the new ca/crt pair in any configuration.
I did actually link my PHP against a copy of LibreSSL 2.3.8, but PHP oddly is unable to use TLS1.1 or 1.2. It does, however, enable EC secp521r1 (of which my native OpenSSL 0.9.8e is incapable).