• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • SSL 上下文选项

    SSL 上下文选项清单

    说明

    ssl://tls://传输协议上下文选项清单。

    可选项

    $peer_namestring

    要连接的服务器名称。如果未设置,那么服务器名称将根据打开 SSL 流的主机名称猜测得出。

    $verify_peerboolean

    是否需要验证 SSL 证书。

    默认值为TRUE

    $verify_peer_nameboolean

    是否需要验证 peer name。

    默认值为TRUE.

    $allow_self_signedboolean

    是否允许自签名证书。需要配合$verify_peer参数使用(注:当 verify_peer 参数为 true 时才会根据 allow_self_signed 参数值来决定是否允许自签名证书)。

    默认值为FALSE

    $cafilestring

    当设置verify_peer为 true 时,用来验证远端证书所用到的 CA 证书。本选项值为 CA 证书在本地文件系统的全路径及文件名。

    $capathstring

    如果未设置cafile,或者cafile所指的文件不存在时,会在capath所指定的目录搜索适用的证书。该目录必须是已经经过哈希处理的证书目录。(注:所谓 hashed certificate 目录是指使用类似 c_rehash 命令将目录中的.pem 和.crt 文件扫描并提取哈希码,然后根据此哈希码创建文件链接,以便于快速查找证书)

    $local_certstring

    本地证书路径。必须是 PEM 格式,并且包含本地的证书及私钥。也可以包含证书颁发者证书链。也可以通过local_pk指定包含私钥的独立文件。

    $local_pkstring

    如果使用独立的文件来存储证书(local_cert)和私钥,那么使用此选项来指明私钥文件的路径。

    $passphrasestring

    local_cert文件的密码。

    $CN_matchstring

    期望远端证书的 CN 名称。 PHP 会进行有限的通配符匹配,如果服务器给出的 CN 名称和本地访问的名称不匹配,则视为连接失败。

    Note:在PHP 5.6.0中,这个选项已废弃,替换为$peer_name

    $verify_depthinteger

    如果证书链条层次太深,超过了本选项的设定值,则终止验证。

    默认情况下不限制证书链条层次深度。

    $ciphersstring

    设置可用的密码列表。可用的值参见:» ciphers(1)。

    默认值为DEFAULT.

    $capture_peer_certboolean

    如果设置为TRUE将会在上下文中创建peer_certificate选项,该选项中包含远端证书。

    $capture_peer_cert_chainboolean

    如果设置为TRUE将会在上下文中创建peer_certificate_chain选项,该选项中包含远端证书链条。

    $SNI_enabledboolean

    设置为TRUE将启用服务器名称指示(server name indication)。启用 SNI 将允许同一 IP 地址使用多个证书。

    $SNI_server_namestring

    如果设置此参数,那么其设置值将被视为 SNI 服务器名称。如果未设置,那么服务器名称将基于打开 SSL 流的主机名称猜测得出。

    Note:在PHP 5.6.0中,这个选项已废弃,替换为$peer_name

    $disable_compressionboolean

    如果设置,则禁用 TLS 压缩,有助于减轻恶意攻击。

    $peer_fingerprintstring| array

    当远程服务器证书的摘要和指定的散列值不相同的时候,终止操作。

    当使用string时,会根据字符串的长度来检测所使用的散列算法:“md5”(32 字节)还是“sha1”(40 字节)。

    当使用array时,数组的键表示散列算法名称,其对应的值是预期的摘要值。

    更新日志

    版本说明
    5.6.0新加$peer_fingerprint参数。
    5.4.13新加$disable_compression。需要 OpenSSL >= 1.0.0.
    5.3.2新加$SNI_enabled$SNI_server_name

    注释

    Note:因为ssl://https://ftps://的底层传输协议,所以,ssl://的上下文选项也同样适用于https://ftps://上下文。

    Note: PHP 必须联合 OpenSSL 0.9.8j 或以上版本编译才可以支持 SNI,同时也支持使用OPENSSL_TLSEXT_SERVER_NAME来探测 SNI 服务器名称。

    参见

    • 套接字上下文选项
    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 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`.
    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.
    If 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 PEM
    It 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).