查看源代码 ssl (ssl v11.2.6)

用于 TLS (传输层安全) 和 DTLS (数据报传输层安全) 的接口函数。

注意

该应用程序的名称仍然是 SSL,因为 TLS 协议的第一个版本被命名为 SSL (安全套接字层)。但是,此应用程序不支持旧版 SSL 协议的任何版本。

示例

1> ssl:start(), ssl:connect("google.com", 443, [{verify, verify_peer},
    {cacerts, public_key:cacerts_get()}]).
{ok,{sslsocket, [...]}}

有关详细用法和此 API 的更多示例,请参阅 示例

有关应用程序的特殊 Erlang 节点配置,请参阅 SSL 应用程序

概要

类型:套接字

以主动模式传递到 TLS/DTLS 套接字所有者的消息的类型。

出于安全原因,默认情况下不再支持的 DTLS 协议版本。

DTLS 协议版本。

如果 TLS 连接失败,将发送/接收 TLS 协议警报。

主机的名称或地址。

客户端 hello 扩展。

TLS 或 DTLS 协议版本。

用于调试的错误原因。

在 TLS-1.3 之前的版本中标识 TLS 会话。

一个套接字,可用于执行所谓的 "START-TLS",这意味着使用先前用于普通 TCP 通信的已连接套接字,并将其升级为使用 TLS。

传输套接字的选项。

对 TLS/DTLS 连接的不透明引用。

TLS 警报协议原因。

可以提供给 TLS 客户端的选项。

出于安全原因,默认情况下不再支持的 TLS 协议版本。

与 TLS/DTLS 协议相关的选项。

可以提供给 TLS 服务器的选项。

TLS 协议版本。

传输选项定义了一个回调模块和消息标签来处理底层传输套接字。

类型:算法

可用于有效负载加密的密码算法。

允许您自定义密码套件列表的过滤器。

应支持的密码套件列表。

密码套件格式。

Erlang 密码套件表示

TLS-1.3 密钥交换配置。

与签名和加密函数一起使用的哈希算法。

密码套件密钥交换算法在 TLS-1.3 中将为 any,因为密钥交换不再是 TLS-1.3 中密码套件配置的一部分。

TLS-1.3 之前的密钥交换配置。

在 TLS-1.3 和 TLS-1.2 中支持。

SHA2 哈希算法。

签名算法。

由 TLS-1.3 定义的签名方案,并取代 TLS-1.2 中的签名算法。

显式列出证书和握手消息的可接受签名算法,并按首选顺序排列。

TLS-1.3 之前的 SRP 密码套件配置。

类型:证书

声明链中的中间 CA 是可信的。

实体证书及其对应密钥的配置。

用于使用内置 CRL 缓存支持的选项。

用户的私钥。

类型:算法(旧版)

出于安全原因,默认情况下不再支持的密码算法。

出于安全原因,默认情况下不再支持的哈希算法。

TLS-1.3 之前的密钥交换配置。

出于安全原因,默认情况下不再支持的签名算法。

如果协商 TLS-1.2,这仅用于证书签名,这意味着对等方仅支持 TLS-1.2,但我们也支持 TLS-1.3。

仅用于向后兼容性;请勿使用。

类型:客户端选项

以下选项是客户端特有的,或者对于客户端和服务器具有不同的语义

特定于客户端的或对于客户端和服务器具有不同语义的与证书相关的选项。

旧版客户端选项。

仅与 TLS-1.3 之前的 TLS 版本相关的选项。

仅与 TLS-1.3 相关的选项。

类型:服务器选项

特定于服务器端的选项,或对于客户端和服务器具有不同的语义。

服务器的与证书相关的选项。

旧版服务器选项。

仅与 TLS-1.3 之前的 TLS 版本相关的选项。

仅与 TLS-1.3 相关的选项。

类型:客户端和服务器选项

客户端和服务器端通用的选项。

客户端和服务器通用的与证书相关的选项。

仅对 DTLS 有效的客户端和服务器通用选项。

旧版选项,被认为已弃用而倾向于其他选项,使用不安全,或者根本不再相关。

TLS-1.3 之前客户端和服务器端通用的选项。

客户端和服务器都通用的 TLS-1.3 的选项。

类型:信息

包含有关已建立连接的一些信息的键值列表。

可以检索信息的 TLS 连接密钥。

与 TLS-1.3 之前的版本相关的 TLS 连接信息。

可用于 NSS 密钥日志记录的 TLS 连接信息。

服务器 API

执行 TLS/DTLS 服务器端握手。

执行 TLS/DTLS 服务器端握手。

创建 SSL 监听套接字。

接受监听套接字上的传入连接请求。

客户端和服务器 API

关闭 TLS/DTLS 连接。

关闭或降级 TLS 连接。

为 SSL 套接字分配新的控制进程。

使用致命的 USER_CANCELED 警报取消握手。

继续 TLS 握手,可能使用新的、附加的或更改的选项。

以被动模式从套接字接收数据包。

Data 写入 SslSocket

根据套接字 SslSocketOptions 设置选项。

立即在一个或两个方向关闭套接字。

仅限 TLS-1.3 API

返回 TLS 1.3 中所有受支持的组。

返回 TLS 1.3 中默认支持的组。

创建新的会话密钥。

Pre TLS-1.3 API

返回所有受支持的椭圆曲线的列表,包括 TLS-1.3 之前的所有 TLS/DTLS 版本的旧版曲线。

返回 Version 默认支持的椭圆曲线。

启动新的握手。

实用函数

使 Deferred 套件成为最不首选的套件。

列出与 Description 对应的所有可用密码套件。

等效于 cipher_suites/2,但列出 RFC 或 OpenSSL 字符串名称,而不是 erl_cipher_suite()

清除 PEM 缓存。

返回有关连接的最相关信息。

如果已定义,则返回有关连接的请求信息项。

使用伪随机函数 (TLS-1.3 之前的 PRF) 或密钥派生函数 (TLS-1.3 中的 HKDF) 进行 TLS 连接,以生成和导出密钥材料。

如果任何过滤器函数对密码套件的任何部分返回 false,则删除密码套件。

将 SSL 函数返回的错误显示为可打印的字符串。

获取指定套接字选项的值。

获取底层套接字的统计信息。

获取底层套接的一个或多个统计值。

返回通过 ALPN 或 NPN 扩展协商的协议。

对等证书以 DER 编码的二进制形式返回。

返回对等方的地址和端口号。

使 Preferred 套件成为最首选的套件。

列出与 Description 对应的所有可用签名算法。

返回套接字 SslSocket 的本地地址和端口号。

等效于 start(temporary)

启动 SSL 应用程序。

停止 SSL 应用程序。

将 RFC 或 OpenSSL 名称字符串转换为 erl_cipher_suite/0

erl_cipher_suite() 值转换为 OpenSSL 名称字符串。

erl_cipher_suite() 值转换为 RFC 名称字符串。

列出运行时信息,主要涉及 TLS/DTLS 版本,用于调试和测试目的。

已弃用的 API

使用 TLS 会话的伪随机函数 (PRF) 生成额外的密钥材料。

类型:Socket

-type active_msgs() ::
          {ssl, sslsocket(), Data :: binary() | list()} |
          {ssl_closed, sslsocket()} |
          {ssl_error, sslsocket(), Alert :: error_alert() | (Reason :: any())} |
          {ssl_passive, sslsocket()}.

以主动模式传递到 TLS/DTLS 套接字所有者的消息的类型。

如果连接建立后发生此类事件,则 ssl_error 原因可能会传达 TLS 协议警报。最常见的情况发生在客户端,当 TLS-1.3 服务器请求客户端证书,而提供的证书未被服务器接受时,因为证书将在服务器发送其最后一个握手消息后进行验证。

仅当套接字处于 {active, N} 模式且计数器降至 0 时,才会发送 ssl_passive 消息。它表示套接字已转换为被动 ({active, false}) 模式。

链接到此类型

dtls_legacy_version()

查看源代码 (未导出)
-type dtls_legacy_version() :: dtlsv1.

出于安全原因,默认情况下不再支持的 DTLS 协议版本。

链接到此类型

dtls_version()

查看源代码 (未导出)
-type dtls_version() :: 'dtlsv1.2' | dtls_legacy_version().

DTLS 协议版本。

-type error_alert() :: {tls_alert, {tls_alert(), Description :: string()}}.

如果 TLS 连接失败,将发送/接收 TLS 协议警报。

将返回一个反映根据 TLS 协议引发的警报的原子和一个包含更多详细信息的描述字符串。

-type host() :: inet:hostname() | inet:ip_address().

主机的名称或地址。

-type protocol_extensions() ::
          #{renegotiation_info => binary(),
            signature_algs => signature_algs(),
            alpn => binary(),
            srp => binary(),
            next_protocol => binary(),
            max_frag_enum => 1..4,
            ec_point_formats => [0..2],
            elliptic_curves => [public_key:oid()],
            sni => inet:hostname()}.

客户端 hello 扩展。

-type protocol_version() :: tls_version() | dtls_version().

TLS 或 DTLS 协议版本。

-type reason() :: term().

用于调试的错误原因。

不匹配。

-type session_id() :: binary().

在 TLS-1.3 之前的版本中标识 TLS 会话。

-type socket() :: gen_tcp:socket().

一个套接字,可用于执行所谓的 "START-TLS",这意味着使用先前用于普通 TCP 通信的已连接套接字,并将其升级为使用 TLS。

双方都需要同意升级。

-type socket_option() :: gen_tcp:connect_option() | gen_tcp:listen_option() | gen_udp:option().

传输套接字的选项。

默认的套接字选项为 [{mode, list}, {packet, 0}, {header, 0}, {active, true}]

有关有效选项,请参阅 Kernel 中的 inetgen_tcpgen_udp。请注意,诸如 packet 之类的面向流的选项仅与 TLS 相关,而与 DTLS 无关。

-type sslsocket() :: any().

对 TLS/DTLS 连接的不透明引用。

请注意,尽管 sslsocket() 实例是不透明的,但允许对其进行匹配。

-type tls_alert() ::
          close_notify | unexpected_message | bad_record_mac | record_overflow | handshake_failure |
          bad_certificate | unsupported_certificate | certificate_revoked | certificate_expired |
          certificate_unknown | illegal_parameter | unknown_ca | access_denied | decode_error |
          decrypt_error | export_restriction | protocol_version | insufficient_security |
          internal_error | inappropriate_fallback | user_canceled | no_renegotiation |
          unsupported_extension | certificate_unobtainable | unrecognized_name |
          bad_certificate_status_response | bad_certificate_hash_value | unknown_psk_identity |
          no_application_protocol.

TLS 警报协议原因。

-type tls_client_option() :: client_option() | common_option() | socket_option() | transport_option().

可以提供给 TLS 客户端的选项。

链接到此类型

tls_legacy_version()

查看源代码 (未导出)
-type tls_legacy_version() :: tlsv1 | 'tlsv1.1'.

出于安全原因,默认情况下不再支持的 TLS 协议版本。

-type tls_option() :: tls_client_option() | tls_server_option().

与 TLS/DTLS 协议相关的选项。

-type tls_server_option() :: server_option() | common_option() | socket_option() | transport_option().

可以提供给 TLS 服务器的选项。

链接到此类型

tls_version()

查看源代码 (未导出)
-type tls_version() :: 'tlsv1.2' | 'tlsv1.3' | tls_legacy_version().

TLS 协议版本。

链接到此类型

transport_option()

查看源代码 (未导出)
-type transport_option() ::
          {cb_info,
           {CallbackModule :: atom(), DataTag :: atom(), ClosedTag :: atom(), ErrTag :: atom()}} |
          {cb_info,
           {CallbackModule :: atom(),
            DataTag :: atom(),
            ClosedTag :: atom(),
            ErrTag :: atom(),
            PassiveTag :: atom()}}.

传输选项定义了一个回调模块和消息标签来处理底层传输套接字。

可用于自定义传输层。标记值应该是底层传输在其主动模式消息中使用的值。

对于 TLS,默认为 {gen_tcp, tcp, tcp_closed, tcp_error, tcp_passive}

注意

为了向后兼容,大小为 4 的元组将转换为大小为 5 的元组,其中 PassiveTag 是附加了 _passiveDataTag 元素。

对于 TLS,回调模块必须实现可靠的传输协议,其行为类似于 gen_tcp,并且具有与 inet:setopts/2inet:getopts/2inet:peername/1inet:sockname/1inet:port/1 对应的函数。回调 gen_tcp 会被特殊处理,并直接调用 inet。对于 DTLS,此功能被认为是实验性的。

类型:算法

-type cipher() ::
          aes_256_gcm | aes_128_gcm | aes_256_ccm | aes_128_ccm | chacha20_poly1305 | aes_256_ccm_8 |
          aes_128_ccm_8 | aes_128_cbc | aes_256_cbc |
          legacy_cipher().

可用于有效负载加密的密码算法。

-type cipher_filters() ::
          [{key_exchange | cipher | mac | prf,
            fun((kex_algo() | cipher() | hash() | aead | default_prf) -> true | false)}].

允许您自定义密码套件列表的过滤器。

链接到此类型

cipher_suites()

查看源代码 (未导出)
-type cipher_suites() :: ciphers().

应支持的密码套件列表。

函数 ssl:cipher_suites/2 可用于查找默认支持的所有密码套件以及可以配置的所有密码套件。

如果你组合自己的 cipher_suites/0,请确保使用 ssl:filter_cipher_suites/2 对它们进行加密库支持的过滤。

以下函数可以帮助创建自定义的密码套件列表

注意

请注意,TLS-1.3 和 TLS-1.2 使用不同的密码套件集。要支持这两个版本,需要包含来自两个集合的密码套件。如果提供的列表不符合配置的版本或加密库,即导致空列表,则该选项将回退到其针对配置版本的相应默认值。

为了互操作性和测试目的,支持非默认密码套件,包括匿名密码套件(在 TLS 1.3 之前)。可以通过将它们添加到密码套件列表中来使用它们。请注意,它们还需要对等方支持并启用才能实际使用,并且可能需要额外的配置;请参阅 srp_param_type()

-type ciphers() :: [erl_cipher_suite()] | string().

密码套件格式。

为了向后兼容,可以将密码套件配置为以冒号分隔的密码套件 RFC 名称(甚至是旧的 OpenSSL 名称)的字符串。但是,如果需要自定义的密码套件选项,更灵活的方法是将实用函数与 cipher_filters() 一起使用。

-type erl_cipher_suite() ::
          #{key_exchange := kex_algo(),
            cipher := cipher(),
            mac := hash() | aead,
            prf := hash() | default_prf}.

Erlang 密码套件表示

警告

强烈不建议启用使用 RSA 作为密钥交换算法的密码套件(仅在 TLS-1.3 之前可用)。对于某些配置,可能存在软件预防措施,并且如果它们起作用,可以使它们可用,但是依赖它们起作用是有风险的。存在更可靠的密码套件可以替代使用。

-type group() ::
          x25519 | x448 | secp256r1 | secp384r1 | secp521r1 | ffdhe2048 | ffdhe3072 | ffdhe4096 |
          ffdhe6144 | ffdhe8192.

TLS-1.3 密钥交换配置。

-type hash() :: sha2() | legacy_hash().

与签名和加密函数一起使用的哈希算法。

-type kex_algo() ::
          ecdhe_ecdsa | ecdh_ecdsa | ecdh_rsa | rsa | dhe_rsa | dhe_dss | srp_rsa | srp_dss | dhe_psk |
          rsa_psk | psk | ecdh_anon | dh_anon | srp_anon | any.

密码套件密钥交换算法在 TLS-1.3 中将为 any,因为密钥交换不再是 TLS-1.3 中密码套件配置的一部分。

-type named_curve() ::
          x25519 | x448 | secp521r1 | brainpoolP512r1 | brainpoolP384r1 | secp384r1 | brainpoolP256r1 |
          secp256r1 |
          legacy_named_curve().

TLS-1.3 之前的密钥交换配置。

链接到此类型

rsassa_pss_scheme()

查看源代码 (未导出)
-type rsassa_pss_scheme() ::
          rsa_pss_rsae_sha512 | rsa_pss_rsae_sha384 | rsa_pss_rsae_sha256 | rsa_pss_pss_sha512 |
          rsa_pss_pss_sha384 | rsa_pss_pss_sha256.

在 TLS-1.3 和 TLS-1.2 中支持。

-type sha2() :: sha512 | sha384 | sha256.

SHA2 哈希算法。

-type sign_algo() :: eddsa | ecdsa | rsa | legacy_sign_algo().

签名算法。

-type sign_scheme() ::
          eddsa_ed25519 | eddsa_ed448 | ecdsa_secp521r1_sha512 | ecdsa_secp384r1_sha384 |
          ecdsa_secp256r1_sha256 | ecdsa_brainpoolP512r1tls13_sha512 |
          ecdsa_brainpoolP384r1tls13_sha384 | ecdsa_brainpoolP256r1tls13_sha256 |
          rsassa_pss_scheme() |
          legacy_sign_scheme().

由 TLS-1.3 定义的签名方案,并取代 TLS-1.2 中的签名算法。

按照首选顺序显式列出可接受的签名方案。

覆盖 signature_algs 选项中为证书提供的算法。除了 TLS 1.2 中的 signature_algorithms 扩展之外,TLS 1.3(RFC 5246 第 4.2.3 节)添加了 signature_algorithms_cert 扩展,该扩展允许对证书中使用的签名有特殊要求,这与对整个数字签名的要求不同。如果不需要,则不需要此扩展。

如果使用 TLS 1.2 版本(在 24.1 中向后移植到 TLS 1.2)或更高版本,并且明确指定了 signature_algs_cert 选项,则客户端将发送 signature_algorithms_cert 扩展(在客户端 Hello 消息中)。默认情况下,仅发送 signature_algs 扩展,除非未明确指定 signature_algs 选项,在这种情况下,它会将 rsa_pkcs1_sha1 算法附加到 signature_algs 的默认值,并将其用作 signature_algs_cert 的值,以允许证书具有此签名,但仍然禁止在 TLS 协议中使用 sha1,自 27.0.1 和 26.2.5.2 起。

注意

请注意,TLS-1.2 支持的签名方案为 legacy_sign_scheme()rsassa_pss_scheme()

-type signature_algs() :: [{hash(), sign_algo()} | sign_scheme()].

显式列出证书和握手消息的可接受签名算法,并按首选顺序排列。

客户端将以客户端 hello signature_algorithm 扩展的形式发送其列表,该扩展在 TLS-1.2 中引入;请参阅 RFC 5246 第 7.4.1.4.1 节。在 TLS-1.2 之前,这些算法是隐式选择的,部分来源于密码套件。

在 TLS-1.2 中,可以使用 {HashAlgo, SignAlgo} 元组列表来实现某种更明确的协商。

在 TLS-1.3 中,这些算法对被与密码套件完全分离的签名方案所取代。

用于证书的签名算法可以被 signature_algs_cert 选项提供的 签名方案覆盖。

TLS-1.2 默认值为 Default_TLS_12_Alg_Pairs,与 ssl-11.0 (Erlang/OTP 25) 以来的 rsa_pss_schemes 交错。 pss_pss 优先于 pss_rsae,而 pss_rsae 又优先于 rsa

Default_TLS_12_Alg_Pairs 的列表定义如下

[
{sha512, ecdsa},
{sha512, rsa},
{sha384, ecdsa},
{sha384, rsa},
{sha256, ecdsa},
{sha256, rsa}
]

更改

  • {md5, rsa} 的支持已从 ssl-8.0 (Erlang/OTP 22) 中的 TLS-1.2 默认值中删除。
  • {sha, _} (SHA1) 和 {sha224, _} 的支持已从 ssl-11.0 (Erlang/OTP 26) 中的 TLS-1.2 默认值中删除。

rsa_pss_schemes 的列表定义如下

[rsa_pss_pss_sha512,
rsa_pss_pss_sha384,
rsa_pss_pss_sha256,
rsa_pss_rsae_sha512,
rsa_pss_rsae_sha384,
rsa_pss_rsae_sha256]

TLS_13_Legacy_Schemes 的列表定义如下

[
%% Legacy algorithms only applicable to certificate signatures
rsa_pkcs1_sha512, %% Corresponds to {sha512, rsa}
rsa_pkcs1_sha384, %% Corresponds to {sha384, rsa}
rsa_pkcs1_sha256, %% Corresponds to {sha256, rsa}
]

Default_TLS_13_Schemes 的列表定义如下

[
%% EDDSA
eddsa_ed25519,
eddsa_ed448

%% ECDSA
ecdsa_secp521r1_sha512,
ecdsa_secp384r1_sha384,
ecdsa_secp256r1_sha256] ++

%% RSASSA-PSS
rsa_pss_schemes()

更改

EDDSA 在 ssl-10.8 (Erlang/OTP 25) 中被设置为最高优先级。

TLS-1.3 默认值为 Default_TLS_13_Schemes

如果同时支持 TLS-1.3 和 TLS-1.2,则默认值为

Default_TLS_13_Schemes ++ TLS_13_Legacy_Schemes ++
Default_TLS_12_Alg_Pairs %% not represented in TLS_13_Legacy_Schemes

以确保可以为协商的版本选择适当的算法。

注意

TLS-1.2 算法不会为 TLS-1.3 进行协商,但 TLS-1.3 RSASSA-PSS (rsassa_pss_scheme()) 签名方案也可以从 Erlang/OTP 24.1(从 Erlang/OTP 24.1.3 开始完全工作)为 TLS-1.2 进行协商。但是,如果使用默认值同时支持 TLS 1.3 和 TLS 1.2,并且协商了 TLS 1.3,则 TLS 1.3 传统签名方案的相应 TLS 1.2 算法将被视为传统方案,并且仅应用于证书签名。

-type srp_param_type() :: srp_8192 | srp_6144 | srp_4096 | srp_3072 | srp_2048 | srp_1536 | srp_1024.

TLS-1.3 之前的 SRP 密码套件配置。

类型:证书

链接到此类型

anchor_fun()

查看源代码 (未导出)
-type anchor_fun() :: fun().

声明链中的中间 CA 是可信的。

fun(Chain::[public_key:der_encoded()]) ->
      {trusted_ca, DerCert::public_key:der_encoded()} | unknown_ca.

然后 TLS 使用 public_key:pkix_path_validation/3,选择的 CA 作为信任锚点,并验证链的其余部分。

-type cert_key_conf() ::
          #{cert => public_key:der_encoded() | [public_key:der_encoded()],
            key => key(),
            certfile => file:filename(),
            keyfile => file:filename(),
            password => iodata() | fun(() -> iodata())}.

实体证书及其对应密钥的配置。

证书(或可能包含证书及其链证书的列表,其中实体证书必须是列表中的第一个元素或文件中的第一个条目)及其关联的密钥。对于 PEM 文件格式,还可以有一个与包含密钥的文件相关联的密码。

为了获得最大的互操作性,链中的证书应按正确的顺序排列,因为链将按原样发送给对等方。如果未提供链证书,则将使用配置的受信任 CA 证书中的证书来构建链。有关更多信息,请参阅 client_option_cert()server_option_cert()

链接到此类型

crl_cache_opts()

查看源代码 (未导出)
-type crl_cache_opts() :: {Module :: atom(), {DbHandle :: internal | term(), Args :: list()}}.

用于使用内置 CRL 缓存支持的选项。

指定如何执行证书吊销列表 (CRL) 的查找和缓存。Module 默认为 ssl_crl_cacheDbHandleinternalArgs[]

有两种可用的实现

  • ssl_crl_cache - 实现 1

    此模块维护 CRL 的缓存。可以使用 ssl_crl_cache:insert/1 将 CRL 添加到缓存中,如果指定以下参数,则可以选择通过 HTTP 自动获取 CRL

  • ssl_crl_hash_dir - 实现 2

    此模块使用一个目录,其中 CRL 存储在以颁发者名称的哈希值命名的文件中。

    文件名由八个十六进制数字组成,后跟 .rN,其中 N 是一个整数,例如 1a2b3c4d.r0。对于 CRL 的第一个版本,N 从零开始,对于每个新版本,N 递增 1。OpenSSL 实用程序 c_rehash 根据此模式创建符号链接。

    对于给定的哈希值,此模块查找从零开始的所有连续 .r* 文件,这些文件加在一起构成吊销列表。将排除 nextUpdate 字段在过去或由恰好具有相同名称哈希值的不同 CA 颁发的 CRL 文件。

    需要以下参数

    • {dir, string()}

    指定可以在其中找到 CRL 的目录。

-type key() ::
          {'RSAPrivateKey' | 'DSAPrivateKey' | 'ECPrivateKey' | 'PrivateKeyInfo',
           public_key:der_encoded()} |
          #{algorithm := sign_algo(),
            engine := crypto:engine_ref(),
            key_id := crypto:key_id(),
            password => crypto:password()} |
          #{algorithm := sign_algo(),
            sign_fun := fun(),
            sign_opts => list(),
            encrypt_fun => fun(),
            encrypt_opts => list()}.

用户的私钥。

密钥可以直接以 DER 编码的实体形式提供,也可以间接使用加密引擎/提供程序(带有密钥参考信息)或作为 Erlang 函数(带有可选的自定义选项)提供。后两种选项可用于使用硬件安全模块 (HSM) 或可信平台模块 (TPM) 进行自定义签名。

类型:算法(旧版)

链接到此类型

legacy_cipher()

查看源代码 (未导出)
-type legacy_cipher() :: '3des_ede_cbc' | des_cbc | rc4_128.

出于安全原因,默认情况下不再支持的密码算法。

链接到此类型

legacy_hash()

查看源代码 (未导出)
-type legacy_hash() :: sha224 | sha | md5.

出于安全原因,默认情况下不再支持的哈希算法。

链接到此类型

legacy_named_curve()

查看源代码 (未导出)
-type legacy_named_curve() ::
          sect571r1 | sect571k1 | sect409k1 | sect409r1 | sect283k1 | sect283r1 | secp256k1 |
          sect239k1 | sect233k1 | sect233r1 | secp224k1 | secp224r1 | sect193r1 | sect193r2 |
          secp192k1 | secp192r1 | sect163k1 | sect163r1 | sect163r2 | secp160k1 | secp160r1 | secp160r2.

TLS-1.3 之前的密钥交换配置。

这些曲线已被 RFC 8422 弃用。

链接到此类型

legacy_sign_algo()

查看源代码 (未导出)
-type legacy_sign_algo() :: dsa.

出于安全原因,默认情况下不再支持的签名算法。

链接到此类型

legacy_sign_scheme()

查看源代码 (未导出)
-type legacy_sign_scheme() ::
          rsa_pkcs1_sha512 | rsa_pkcs1_sha384 | rsa_pkcs1_sha256 | ecdsa_sha1 | rsa_pkcs1_sha1.

如果协商 TLS-1.2,这仅用于证书签名,这意味着对等方仅支持 TLS-1.2,但我们也支持 TLS-1.3。

-type old_cipher_suite() ::
          {kex_algo(), cipher(), hash()} | {kex_algo(), cipher(), hash() | aead, hash()}.

仅用于向后兼容性;请勿使用。

类型:客户端选项

链接到此类型

client_option()

查看源代码 (未导出)
-type client_option() ::
          client_option_cert() |
          common_option_cert() |
          {alpn_advertised_protocols, AppProtocols :: [AppProto :: binary()]} |
          {max_fragment_length, MaxLen :: undefined | 512 | 1024 | 2048 | 4096} |
          client_option_tls13() |
          common_option_tls13() |
          client_option_pre_tls13() |
          common_option_pre_tls13() |
          common_option_dtls() |
          client_option_legacy() |
          common_option_legacy().

以下选项是客户端特有的,或者对于客户端和服务器具有不同的语义

  • {alpn_advertised_protocols, AppProtocols} - 应用层协议

    客户端支持的协议列表,将发送到服务器以用于应用层协议协商 (ALPN)。如果服务器支持 ALPN,它将从此列表中选择一个协议;否则,它将使用 no_application_protocol 警报使连接失败。不支持 ALPN 的服务器将忽略此值。协议列表不能包含空二进制。

  • {max_fragment_length, MaxLen} - 最大分段长度扩展

    指定客户端准备从服务器接受的最大分段长度。请参阅 RFC 6066

-type client_option_cert() ::
          {verify, Verify :: verify_peer | verify_none} |
          {cacerts, CACerts :: [public_key:der_encoded()] | [public_key:combined_cert()]} |
          {cacertfile, CACertFile :: file:filename()} |
          {server_name_indication, SNI :: inet:hostname() | disable} |
          {customize_hostname_check, HostNameCheckOpts :: list()} |
          {certificate_authorities, boolean()} |
          {stapling, Stapling :: staple | no_staple | map()}.

特定于客户端的或对于客户端和服务器具有不同语义的与证书相关的选项。

  • {verify, Verify} - 证书验证

    此选项指定是否要验证证书。

    如果 Verifyverify_peer(默认值),则还需要提供选项 cacertscacertfile 之一,才能使证书验证成功。例如,HTTPS 客户端可以使用选项 {cacerts, public_key:cacerts_get()} 来使用操作系统提供的受信任 CA 证书。

    如果 Verifyverify_none,则将忽略所有 X.509 证书路径验证错误。

    更改

    在 Erlang/OTP 26 中,Verify 的默认值已更改为 verify_peer

  • {cacerts, CACerts} - 受信任的证书

    DER 编码的受信任证书。如果提供了此选项,它将覆盖选项 cacertfile

    可以使用函数 public_key:cacerts_get/0 来检索操作系统提供的受信任 CA 证书。

  • {cacertfile, CertFile} - 终端实体证书

    包含 PEM 编码的 CA 证书的文件的路径。CA 证书在服务器身份验证和构建客户端证书链时使用。

    注意

    启用 PEM 缓存后,将以 ssl_pem_cache_clean 环境参数指定的固定时间间隔检查使用此选项提供的文件是否存在更新。

  • {server_name_indication, SNI} - 服务器名称指示扩展

    指定要在 TLS 服务器名称指示扩展中使用的主机名。如果未指定,它将默认为 connect/3,4Host 参数,除非它是类型 inet:ip_address()。主机名也将用于使用 public_key:pkix_verify_hostname/2 验证对等证书的主机名。特殊值 disable 阻止发送服务器名称指示扩展并禁用主机名验证检查。

  • {customize_hostname_check, HostNameCheckOpts} - 自定义选项

    自定义对等证书的主机名验证,因为使用 TLS 的各种协议(例如 HTTP 或 LDAP)可能需要不同的方法。例如,以下是如何使用 Public_Key 中实现的 HTTPS 的标准主机名检查

    {customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]}

    有关自定义选项的更多描述,请参阅 public_key:pkix_verify_hostname/3

  • {client_certificate_authorities, UseCertAuth} - 互操作提示选项

    如果将 UseCertAuth 设置为 true,则会在 TLS-1.3 客户端 hello 中发送证书颁发机构扩展。默认值为 false。请注意,如果存在许多受信任的 CA 证书,则将 UseCertAuth 设置为 true 可能会导致显著的开销。(自 Erlang/OTP 24.3 起。)

  • {stapling, Stapling} - 证书吊销检查选项

    如果 Stapling 是原子 staple 或映射,则将启用 OCSP 装订,这意味着类型为“status_request”的扩展将包含在客户端 hello 中,以指示接收证书状态信息的意愿。

    如果将 Stapling 设置为 no_staple(默认值),则将禁用 OCSP 装订。

    注意

    即使客户端请求,服务器也可能不提供 OCSP 响应。在这种情况下,SSL 将继续握手并生成一个 {missing, stapling_response} 日志记录器事件。

    Stapling 作为映射给出时,布尔值 ocsp_nonce 键可以指示客户端是否应请求 OCSP 随机数(默认值为 false)。

    注意

    即使客户端请求了 nonce 值,OCSP 响应也可以不提供 nonce 值。在这种情况下,SSL 将继续握手并生成一个 {missing, ocsp_nonce} 日志事件。

链接到此类型

client_option_legacy()

查看源代码 (未导出)
-type client_option_legacy() ::
          {client_preferred_next_protocols,
           NextAppProtocols ::
               {Precedence :: server | client, ClientPrefs :: [AppProto :: binary()]} |
               {Precedence :: server | client,
                ClientPrefs :: [AppProto :: binary()],
                Default :: (AppProto :: binary())}}.

旧版客户端选项。

  • {client_preferred_next_protocols, NextAppProtocols} - 下一个协议协商

    ALPN(应用层协议协商)弃用了 NPN(下一个协议协商)和此选项。

    表示客户端希望执行下一个协议协商。

    如果 Precedenceserver,则协商的协议是服务器通告列表中第一个同时也在客户端首选列表中的协议。

    如果 Precedenceclient,则协商的协议是客户端首选列表中第一个同时也在服务器通告列表中的协议。

    如果客户端不支持任何服务器通告的协议,或者服务器未通告任何协议,则客户端将回退到其列表中的第一个协议,或回退到默认协议(如果提供了默认协议)。如果服务器不支持下一个协议协商,并且没有提供默认协议,则连接将终止。

链接到此类型

client_option_pre_tls13()

查看源代码 (未导出)
-type client_option_pre_tls13() ::
          {reuse_session, SessionRef :: session_id() | {session_id(), SessionData :: binary()}} |
          {reuse_sessions, Reuse :: boolean() | save} |
          {psk_identity, PskID :: string()} |
          {srp_identity, SrpID :: {Username :: string(), Password :: string()}} |
          {fallback, LegacyFallback :: boolean()}.

仅与 TLS-1.3 之前的 TLS 版本相关的选项。

  • {reuse_session, SessionRef} - 显式会话重用

    重用特定的会话。

    自 Erlang/OTP 21.3 起,如果会话之前使用选项 {reuse_sessions, save} 保存,则可以通过其会话 ID 引用该会话。

    自 Erlang/OTP 22.3 起,可以通过其会话 ID 和关联的数据显式指定会话。

    另请参阅 SSL 用户指南,TLS 1.3 之前的会话重用。

  • {reuse_sessions, Reuse} - 启用稍后会话重用

    Reuse 设置为 save 时,将协商并保存新连接以供稍后重用。可以使用 connection_information/2 获取会话 ID,并将其与客户端选项 reuse_session 一起使用。

    Reuse 设置为 true 时,如果可能,将执行自动会话重用。如果创建了新会话,并且相对于之前存储的会话是唯一的,则会保存该会话以供稍后重用。

    自:OTP 21.3。

  • {psk_identity, PskID} - 用于 PSK 密码套件的选项

    指定客户端呈现给服务器的身份。匹配的密钥由 user_lookup_fun 选项中给出的 fun 查找。

  • {srp_identity, SrpID} - 用于 SRP 密码套件的选项

    指定用于向服务器进行身份验证的用户名和密码。

  • {fallback, LegacyFallback} - 互操作旧版客户端选项

    发送特殊的密码套件 TLS_FALLBACK_SCSV,以避免不希望的 TLS 版本降级。默认为 false

    警告

    在正常的 TLS 用法中不需要此选项,并且不得使用它来实现新的客户端。但是,以以下方式重试连接的旧版客户端

    ssl:connect(Host, Port, [...{versions, ['tlsv2', 'tlsv1.1', 'tlsv1']}])

    ssl:connect(Host, Port, [...{versions, [tlsv1.1', 'tlsv1']}, {fallback, true}])

    ssl:connect(Host, Port, [...{versions, ['tlsv1']}, {fallback, true}])

    可以使用它来避免不希望的 TLS 版本降级。请注意,TLS_FALLBACK_SCSV 也必须由服务器支持,才能实现预防功能。

链接到此类型

client_option_tls13()

查看源代码 (未导出)
-type client_option_tls13() ::
          {session_tickets, SessionTickets :: disabled | manual | auto} |
          {use_ticket, Tickets :: [binary()]} |
          {early_data, binary()} |
          {middlebox_comp_mode, MiddleBoxMode :: boolean()}.

仅与 TLS-1.3 相关的选项。

  • {session_tickets, SessionTickets} - 会话票证的使用

    配置会话票证功能。允许的值为 disabledmanualauto。如果设置为 manual,客户端会将票证信息以 3 元组的形式发送给用户进程

    {ssl, session_ticket, {SNI, TicketData}}

    其中 SNI 是 ServerNameIndication,TicketData 是扩展的票证数据,可用于后续会话恢复。

    如果设置为 auto,客户端会自动处理收到的票证,并在建立新的 TLS 连接时尝试使用它们(使用预共享密钥进行会话恢复)。

    票证生存期、服务器发送的票证数量以及服务器在有状态模式下存储的最大票证数量由 应用程序变量 配置。

    另请参阅 SSL 用户指南,TLS 1.3 中的会话票证和会话恢复

  • {use_ticket, Tickets}

    配置用于会话恢复的会话票证。在 manual 模式 ({session_tickets, manual}) 中是必需的选项。

    注意

    仅当选项 session_tickets 设置为 manual 时,才会将会话票证发送给用户。

    TLS-1.3 支持此选项。另请参阅 SSL 用户指南,TLS 1.3 中的会话票证和会话恢复

  • {early_data, EarlyData}

    配置客户端要发送的早期数据。

    为了验证服务器是否有意处理早期数据,以下元组会发送给用户进程

    {ssl, SslSocket, {early_data, Result}}

    其中 Resultacceptedrejected

    警告

    用户有责任处理被拒绝的 EarlyData 并在适当时重新发送。

  • {middlebox_comp_mode, MiddleBoxMode}

    为 TLS-1.3 连接配置中间盒兼容模式。

    当协商 TLS-1.3 连接时,大量中间盒会表现异常。通过调整 TLS-1.3 握手使其类似于 TLS-1.2 握手,实现可以增加通过这些中间盒建立连接的机会。

    默认情况下,中间盒兼容模式已启用 (true)。

类型:服务器选项

链接到此类型

server_option()

查看源代码 (未导出)
-type server_option() ::
          server_option_cert() |
          common_option_cert() |
          {alpn_preferred_protocols, AppProtocols :: [binary()]} |
          {sni_hosts, SNIHosts :: [{inet:hostname(), [server_option() | common_option()]}]} |
          {sni_fun, SNIFun :: fun((string()) -> [])} |
          server_option_pre_tls13() |
          common_option_pre_tls13() |
          server_option_tls13() |
          common_option_tls13() |
          common_option_dtls() |
          server_option_legacy() |
          common_option_legacy().

特定于服务器端的选项,或对于客户端和服务器具有不同的语义。

  • {alpn_preferred_protocols, AppProtocols} - 应用层协议协商

    表示服务器将尝试执行应用层协议协商 (ALPN)。

    协议列表按首选顺序排列。协商的协议将是列表中与客户端通告的协议之一匹配的第一个协议。如果没有协议匹配,服务器将使用 no_application_protocol 警报使连接失败。

    可以使用 negotiated_protocol/1 函数检索协商的协议。

  • {sni_fun, SNIFun}

    如果服务器从客户端收到 SNI(服务器名称指示),则将调用给定的 fun SNIFun 以检索指示主机的 server_option()。这些选项将覆盖该主机先前指定的选项。

    注意

    选项 sni_funsni_hosts 是互斥的。

  • {sni_hosts, SNIHosts}

    如果服务器从客户端收到与 sni_hosts 选项中列出的主机匹配的 SNI(服务器名称指示),则该主机的特定选项将覆盖先前指定的选项。

    注意

    选项 sni_funsni_hosts 是互斥的。

-type server_option_cert() ::
          {cacerts, CACerts :: [public_key:der_encoded()] | [public_key:combined_cert()]} |
          {cacertfile, CACertFile :: file:filename()} |
          {verify, Verify :: verify_none | verify_peer} |
          {fail_if_no_peer_cert, FailNoPeerCert :: boolean()} |
          {certificate_authorities, ServerCertAuth :: boolean()}.

服务器的与证书相关的选项。

  • {cacerts, CACerts} - 受信任的证书。

    DER 编码的受信任证书。如果提供此选项,它将覆盖 cacertfile 选项。

  • {verify, Verify} - 验证证书。

    客户端证书是 TLS 协议的可选部分。服务器仅在 verify_peer 模式下执行 X.509 证书路径验证。默认情况下,服务器处于 verify_none 模式,因此不会向客户端发送证书请求。使用 verify_peer 时,您可能还希望指定选项 fail_if_no_peer_certcertificate_authorities

  • {fail_if_no_peer_cert, FailNoPeerCert} - 旧版权衡选项

    由 TLS/DTLS 服务器与 {verify, verify_peer} 一起使用。如果设置为 true,如果客户端没有要发送的证书(即发送空证书),则服务器将失败。如果设置为 false,则仅当客户端发送无效证书时才会失败(空证书被视为有效)。默认为 false

  • {certificate_authorities, ServerCertAuth} - 互操作提示选项

    确定 TLS-1.3 服务器是否应在其证书请求消息中包含 authorities 扩展,该消息在选项 verify 设置为 verify_peer 时发送。默认为 true

    如果为较旧的 TLS 版本设置为 false,则其证书请求中相应的证书颁发机构定义将设置为空列表,而不是包含适当的证书颁发机构。这与排除 TLS-1.3 扩展具有相同的效果。

    排除扩展的原因可能是服务器希望与无法发送符合该扩展的完整证书链的客户端进行通信,但服务器仍然有能力重建它可以验证的链。

链接到此类型

server_option_legacy()

查看源代码 (未导出)
-type server_option_legacy() :: {next_protocols_advertised, NextAppProtocols :: [binary()]}.

旧版服务器选项。

  • {next_protocols_advertised, NextAppProtocols}

    ALPN(应用层协议协商)弃用了此处描述的 NPN(下一协议协商)。

    如果客户端表明它支持下一协议扩展,则发送给客户端的协议列表。客户端可以选择不在该列表中的协议。协议列表不得包含空二进制。如果服务器协商了下一协议,可以使用 negotiated_protocol/1 方法访问。

链接到此类型

server_option_pre_tls13()

查看源代码 (未导出)
-type server_option_pre_tls13() ::
          {client_renegotiation, ClientRengotiation :: boolean()} |
          {reuse_sessions, ReuseSessions :: boolean()} |
          {reuse_session, ReuseSession :: fun()} |
          {honor_cipher_order, HonorServerCipherOrder :: boolean()} |
          {honor_ecc_order, HonorServerECCOrder :: boolean()} |
          {dh, DHDer :: public_key:der_encoded()} |
          {dhfile, DhFile :: file:filename()} |
          {psk_identity, PSKHint :: string()}.

仅与 TLS-1.3 之前的 TLS 版本相关的选项。

  • {client_renegotiation, ClientRengotiation} - 避免 DoS 攻击的选项

    在支持客户端发起的重新协商的协议中,此类操作对服务器的资源消耗高于客户端。这可能成为拒绝服务 (DoS) 攻击的载体。SSL 应用程序已经采取措施来应对此类尝试,但可以通过将此选项设置为 false 来完全禁用客户端发起的重新协商。默认值为 true。请注意,禁用重新协商可能会导致长期存在的连接由于底层密码套件可以加密的消息数量限制而变得不可用。

  • {reuse_sessions, ReuseSessions} - 启用会话重用

    布尔值 true 指定服务器将同意重用会话。将其设置为 false 将导致一个空的会话表,这意味着不会重用任何会话。

  • {reuse_session, ReuseSession} - 本地服务器重用策略

    使 TLS/DTLS 服务器能够拥有本地策略,以决定是否重用会话。仅当 reuse_sessions 设置为 true 时才有意义。

    ReuseSession 应该是一个函数

    fun(SuggestedSessionId, PeerCert, Compression, CipherSuite)

    SuggestedSessionId 是一个 binary()PeerCert 是 DER 编码的证书,Compression 是一个枚举整数,CipherSuite 的类型为 erl_cipher_suite()

  • {psk_identity, PSKHint} - 互操作提示选项

    指定服务器向客户端提供的服务器身份提示。

  • {honor_cipher_order, HonorServerCipherOrder} - 权衡选项,改变协议定义的行为

    如果 true,则使用服务器对 ECC 曲线选择的偏好。如果 false(默认值),则使用客户端的偏好。

  • {honor_ecc_order, HonorServerECCOrder} - 权衡选项,改变协议定义的行为

    如果 true,则使用服务器对 ECC 曲线选择的偏好。如果 false(默认值),则使用客户端的偏好。

  • {dh, DHder} - 影响 DH 密钥交换密码套件

    DER 编码的 Diffie-Hellman 参数。如果指定,它将覆盖选项 dhfile

  • {dh_file, DHfile} - 影响 DH 密钥交换密码套件

    包含 PEM 编码的 Diffie Hellman 参数的文件的路径,如果协商了使用 Diffie Hellman 密钥交换的密码套件,则服务器将使用这些参数。如果未指定,则使用默认参数。

链接到此类型

server_option_tls13()

查看源代码 (未导出)
-type server_option_tls13() ::
          {session_tickets,
           SessionTickets :: disabled | stateful | stateless | stateful_with_cert | stateless_with_cert} |
          {stateless_tickets_seed, TicketSeed :: binary()} |
          {anti_replay,
           '10k' | '100k' |
           {BloomFilterWindowSize :: pos_integer(),
            BloomFilterHashFunctions :: pos_integer(),
            BloomFilterBits :: pos_integer()}} |
          {cookie, Cookie :: boolean()} |
          {early_data, EarlyData :: enabled | disabled}.

仅与 TLS-1.3 相关的选项。

  • {session_tickets, SessionTickets}

    配置会话票证功能。SessionTickets 的允许值为

    • disabled
    • stateful
    • stateless
    • stateful_with_cert
    • stateless_with_cert

    如果 SessionTickets 未设置为 disabled,则启用使用预共享密钥的会话恢复,并且服务器将在成功连接后向客户端发送有状态或无状态的会话票证。

    注意

    在预共享密钥会话票证恢复中,不涉及证书交换。因此,ssl:peercert/1 不会返回对等证书,因为它仅在初始握手期间进行通信。要将原始握手中的客户端证书与它发出的票证相关联,可以使用服务器选项 stateful_with_certstateless_with_cert

    有状态会话票证是指向内部状态信息的数据库引用。无状态会话票证是一个自加密的二进制文件,其中包含加密密钥材料和状态数据。

    警告

    SessionTickets 设置为 stateful_with_cert 时,客户端证书将与内部状态信息一起存储,从而导致内存消耗增加。相反,当它设置为 stateless_with_cert 时,客户端证书将编码在发送给客户端的自加密二进制文件中,从而导致有效负载大小增加。

    另请参阅 SSL 用户指南,TLS 1.3 中的会话票证和会话恢复

  • {stateless_tickets_seed, TicketSeed} - 无状态票证的选项

    配置用于加密无状态会话票证的种子。允许的值是任何随机生成的 binary/0。如果未配置此选项,将随机生成加密种子。

    警告

    在多个服务器实例之间重用票证加密种子使无状态会话票证能够在多个服务器实例之间工作,但这会破坏跨实例的防重放保护。

    服务器实例之间不准确的时间同步也可能影响会话票证新鲜度检查,从而可能导致误报以及误报。

  • {anti_replay, AntiReplay} - 无状态票证的选项

    根据布隆过滤器配置服务器的内置防重放功能。

    AntiReplay 的允许值是预定义的 '10k''100k' 或定义布隆过滤器属性的自定义 3 元组:{WindowSize, HashFunctions, Bits}WindowSize 是在当前布隆过滤器轮换后以及用于 ClientHello 新鲜度检查的窗口大小的秒数。HashFunctions 是哈希函数的数量,Bits 是位向量中的位数。'10k''100k' 是具有以下属性的简单默认值

    • '10k':布隆过滤器可以容纳 10000 个元素,且误报率为 3%。WindowSize:10,HashFunctions:5,Bits: 72985 (8.91 KiB)。
    • '100k':布隆过滤器可以容纳 100000 个元素,且误报率为 3%。WindowSize:10,HashFunctions:5,Bits:729845 (89.09 KiB)。

    另请参阅 SSL 用户指南,TLS 1.3 中的防重放保护

  • {cookie, Cookie} - HelloRetryRequest 行为的选项

    如果 Cookietrue,这是默认值,则服务器在其 HelloRetryRequest 消息中发送 cookie 扩展。

    cookie 扩展有两个主要目的。它允许服务器强制客户端在其明显的网络地址处演示可达性(从而提供一定的 DoS 保护)。这对于非面向连接的传输主要有用。它还允许将服务器的状态卸载到客户端。默认情况下启用 cookie 扩展,因为它是 RFC8446 中的强制扩展。

  • {early_data, EarlyData} - 接受或拒绝早期数据的选项

    配置服务器是否接受(enabled)或拒绝(disabled)客户端发送的早期数据。默认值为 disabled

类型:客户端和服务器选项

链接到此类型

common_option()

查看源代码 (未导出)
-type common_option() ::
          {protocol, tls | dtls} |
          {handshake, hello | full} |
          {ciphers, cipher_suites()} |
          {signature_algs, signature_algs()} |
          {signature_algs_cert, [sign_scheme()]} |
          {keep_secrets, KeepSecrets :: boolean()} |
          {max_handshake_size, HandshakeSize :: pos_integer()} |
          {versions, [protocol_version()]} |
          {log_level, Level :: logger:level() | none | all} |
          {hibernate_after, HibernateTimeout :: timeout()} |
          {receiver_spawn_opts, SpawnOpts :: [erlang:spawn_opt_option()]} |
          {sender_spawn_opts, SpawnOpts :: [erlang:spawn_opt_option()]}.

客户端和服务器端通用的选项。

  • {protocol, Protocol} - 为传输层安全性选择 TLS 或 DTLS 协议。

    默认为 tls

  • {handshake, Completion} - 可能在 hello 阶段暂停握手。

    默认为 full。如果指定 hello,则握手将在 hello 消息后暂停,允许用户在继续或中止握手之前基于 hello 扩展做出决策,方法是调用 handshake_continue/3handshake_cancel/1

  • {keep_secrets, KeepSecrets} - 配置 TLS 1.3 连接以进行密钥记录。

    为了检索 TLS 1.3 连接上的密钥日志信息,必须预先配置为保留 client_random 和各种握手密钥。

    keep_secrets 功能默认情况下禁用 (false)。

    在 OTP 23.2 中添加。

  • {max_handshake_size, HandshakeSize} - 限制可接受的握手数据包大小。

    用于限制有效 TLS 握手数据包的大小,以避免 DoS 攻击。

    整数(24 位,无符号)。默认为 256*1024

  • {hibernate_after, HibernateTimeout} - 休眠不活动的连接进程。

    当指定整数值时,TLS/DTLS 连接在指定的非活动毫秒数后进入休眠状态,从而减少其内存占用。如果未指定,则进程永远不会进入休眠状态。

  • {log_level, Level} - 指定 TLS/DTLS 连接的日志级别。

    警报记录在 notice 级别,这是默认级别。debug 级别触发 TLS/DTLS 协议消息的详细日志记录。另请参阅 SSL 应用程序

  • {receiver|sender_spawn_opts, SpawnOpts} - 配置 erlang spawn opts。

    配置 TLS 发送方和接收方进程的 spawn 选项。

    设置垃圾回收选项有助于在 CPU 使用率和内存使用率之间进行权衡。请参阅 erlang:spawn_opt/2

    对于使用 Erlang 分布的连接,默认发送方选项为 [...{priority, max}];此优先级选项无法更改。对于所有连接,...link 将添加到接收方,并且无法更改。

链接到此类型

common_option_cert()

查看源代码 (未导出)
-type common_option_cert() ::
          {certs_keys, CertsKeys :: [cert_key_conf()]} |
          {depth, AllowedCertChainLen :: pos_integer()} |
          {verify_fun, Verify :: {Verifyfun :: fun(), InitialUserState :: any()}} |
          {cert_policy_opts,
           PolicyOpts ::
               [{policy_set, [public_key:oid()]} |
                {explicit_policy, boolean()} |
                {inhibit_policy_mapping, boolean()} |
                {inhibit_any_policy, boolean()}]} |
          {allow_any_ca_purpose, Allow :: boolean()} |
          {crl_check, Check :: boolean() | peer | best_effort} |
          {crl_cache, crl_cache_opts()} |
          {partial_chain, anchor_fun()}.

客户端和服务器通用的与证书相关的选项。

  • {certs_keys, CertsKeys} - 至少一个证书和密钥对。

    一个证书列表(或者可能是证书及其链)以及可用于验证客户端或服务器的证书的相关密钥。将选择被认为最佳且与连接的协商参数匹配的证书密钥对。

    不同的签名算法按以下顺序排列优先级:eddsaecdsarsa_pss_pssrsadsa。如果为同一签名算法提供了多个密钥,则将按强度排列优先级(*引擎密钥*除外;请参阅下一段)。这提供了灵活性,例如,配置一个预计在大多数情况下使用的新证书,以及一个较旧但可接受的证书,该证书仅用于与旧系统通信。请注意,诱导开销和灵活性之间存在权衡;因此,应该出于充分的理由选择替代方案。

    引擎密钥将优先于其他密钥。由于无法检查引擎密钥,因此提供多个引擎密钥毫无意义。

    指定此选项后,它将覆盖所有单个证书和密钥选项。有关示例,请参见用户指南

    注意

    eddsa 证书仅受不支持 dsa 证书的 TLS-1.3 实现支持。rsa_pss_pss(使用概率签名方案的 RSA 证书)在 TLS-1.2 和 TLS-1.3 中受支持,但某些 TLS-1.2 实现不支持 rsa_pss_pss

  • {depth, AllowedCertChainLen} - 限制证书链中允许的证书数量。

    在有效的证书路径中,对等证书之后可以跟的最大非自颁发中间证书数量。因此,如果深度为 0,则对等方必须由受信任的 ROOT-CA 直接签名;如果深度为 1,则路径可以是 PEER、CA、ROOT-CA;如果深度为 2,则路径可以是 PEER、CA、CA、ROOT-CA,依此类推。默认值为 10。用于缓解 DoS 攻击的可能性。

  • {verify_fun, Verify} - 自定义证书路径验证

    验证函数定义如下

    fun(OtpCert :: #'OTPCertificate'{},
        Event, InitialUserState :: term()) ->
      {valid, UserState :: term()} |
      {fail, Reason :: term()} | {unknown, UserState :: term()}.
    
    fun(OtpCert :: #'OTPCertificate'{}, DerCert :: public_key:der_encoded(),
        Event, InitialUserState :: term()) ->
      {valid, UserState :: term()} |
      {fail, Reason :: term()} | {unknown, UserState :: term()}.
    
    Types:
          Event = {bad_cert, Reason :: atom() |
                  {revoked, atom()}} |
          {extension, #'Extension'{}} |
                  valid |
                  valid_peer

    当发生错误或遇到 SSL 应用程序未知的扩展时,在 X.509 路径验证期间调用验证函数。当路径验证认为证书有效时,也会调用它以允许用户应用程序访问路径中的每个证书。它通过使用 valid_peervalid 作为验证函数的 Event 参数来区分对等证书和 CA 证书。有关 #'OTPCertificate'{}#'Extension'{} 的定义,请参阅Public_Key 用户指南

    • 如果验证回调函数返回 {fail, Reason},则验证过程将立即停止,向对等方发送警报,并且 TLS/DTLS 握手终止。
    • 如果验证回调函数返回 {valid, UserState},则验证过程继续。
    • 如果验证回调函数始终返回 {valid, UserState},则无论验证失败如何,TLS/DTLS 握手都不会终止,并且将建立连接。
    • 如果调用了用户应用程序未知的扩展,则该函数应返回 {unknown, UserState}

    请注意,如果某个扩展被标记为关键扩展,而该函数返回 unknown,则验证将失败。

    verify_peer 模式下的默认选项 verify_fun

    {fun(_, _, {bad_cert, _} = Reason, _) ->
       {fail, Reason};
        (_, _, {extension, _}, UserState) ->
       {unknown, UserState};
        (_, _, valid, UserState) ->
       {valid, UserState};
        (_, _, valid_peer, UserState) ->
           {valid, UserState}
     end, []}

    模式 verify_none 中的默认选项 verify_fun

     {fun(_, _, {bad_cert, _}, UserState) ->
       {valid, UserState};
        (_, _, {extension, #'Extension'{critical = true}}, UserState) ->
       {valid, UserState};
        (_, _, {extension, _}, UserState) ->
       {unknown, UserState};
        (_, _, valid, UserState) ->
       {valid, UserState};
        (_, _, valid_peer, UserState) ->
           {valid, UserState}
     end, []}

    可能的路径验证错误以 {bad_cert, Reason} 的形式给出,其中 Reason

    • unknown_ca

      在受信任的存储中未找到受信任的 CA。受信任的 CA 通常是所谓的 ROOT CA,它是一个自签名证书。可以通过使用选项 partial_chain 为中间 CA(根据 X-509,受信任的锚点不必是自签名的)声明信任。

    • selfsigned_peer

      该链仅由一个自签名证书组成。

    • {invalid_ext_keyusage, [public_key:oid()]}

    如果对等证书指定了扩展密钥用法扩展,并且未包含作为 TLS 服务器(id-kp-ServerAuth)或 TLS 客户端(id-kp-ClientAuth)的目的,具体取决于对等方的角色。

    • {ca_invalid_ext_keyusage, [public_key:oid()]}

    如果 CA 证书指定了扩展密钥用法扩展,并且未包含作为 TLS 服务器(id-kp-ServerAuth)或 TLS 客户端(id-kp-ClientAuth)的目的,具体取决于与此 CA 链接的对等方的角色,或者选项 allow_any_ca_purpose 设置为 true,但 CA 证书目的中不包含特殊值 (anyExtendedKeyUsage)。

  • {cert_policy_opts, PolicyOpts} - 处理证书策略。

    配置证书路径验证过程的 X.509 证书策略处理;有关更多详细信息,请参阅 public_key:pkix_path_validation/3

  • {allow_any_ca_purpose, boolean()} - 处理证书扩展密钥用法扩展

    如果 CA 证书具有扩展密钥用法扩展,但不希望限制密钥的用法,则可以包含一个特殊的 anyExtendedKeyUsage 目的。如果此选项设置为 true,则会自动接受包含该目的的 CA 的所有密钥用法目的,该选项默认为 false。

  • {cerl_check, Check} - 处理证书吊销列表。

    在证书链的路径验证 (public_key:pkix_path_validation/3) 期间,对所有证书执行 CRL(证书吊销列表)验证 (public_key:pkix_crls_validate/3)Check 默认为 false

    Check 的含义如下

    • false

      不执行任何检查。

    • peer

      仅对对等证书执行检查。

    • best_effort

      如果无法确定证书吊销状态,则会将其接受为有效。

      为连接指定的 CA 证书将用于构建验证 CRL 的证书链。

      CRL 将从本地或外部缓存中获取。请参阅 ssl_crl_cache_api

链接到此类型

common_option_dtls()

查看源代码 (未导出)
-type common_option_dtls() ::
          {use_srtp, UseSrtp :: #{protection_profiles := [binary()], mki => binary()}}.

仅对 DTLS 有效的客户端和服务器通用选项。

  • {use_srtp, UseSrtp} - 配置 use_srtp DTLS hello 扩展。

    为了协商使用 SRTP 数据保护,客户端在 DTLS 扩展客户端 hello 中包含一个类型为“use_srtp”的扩展。仅当传输的数据是 RTP 或 RTCP 时,才必须使用此扩展。

    该值是一个映射,其中包含强制性 protection_profiles 参数和一个可选的 mki 参数。

    protection_profiles 配置客户端可接受的 SRTP 保护配置文件列表。每个配置文件都是一个 2 字节的二进制文件。示例:#{protection_profiles => [<<0,2>>, <<0,5>>]}

    mki 配置客户端选择的 SRTP 主密钥标识符。

    srtp_mki 字段包含与由此握手派生的 SRTP 主密钥关联的 SRTP MKI 的值。每个 SRTP 会话在任何给定时间都必须只有一个主密钥,该主密钥用于保护数据包。客户端必须选择 MKI 值,使其与上次使用的 MKI 值不同,并且应使这些值在 TLS 会话期间保持唯一。

    注意

    OTP 不处理 SRTP,因此需要 SRTP 编码器/解码器和数据包多路分解器的外部实现才能使用 use_srtp 扩展。另请参阅选项 transport_option

    收到包含“use_srtp”扩展的扩展 hello 的服务器可以通过在扩展服务器 hello 中包含一个类型为“use_srtp”的扩展(带有选择的保护配置文件)来同意使用 SRTP。仅当传输的数据是 RTP 或 RTCP 时,才必须使用此扩展。

链接到此类型

common_option_legacy()

查看源代码 (未导出)
-type common_option_legacy() ::
          {cert, Cert :: public_key:der_encoded() | [public_key:der_encoded()]} |
          {certfile, CertPem :: file:filename()} |
          {key, Key :: key()} |
          {keyfile, KeyPem :: file:filename()} |
          {password, KeyPemPasswd :: iodata() | fun(() -> iodata())} |
          {log_alert, LogAlert :: boolean()} |
          {padding_check, PaddingCheck :: boolean()} |
          {beast_mitigation, one_n_minus_one | zero_n | disabled} |
          {ssl_imp, Imp :: new | old}.

旧版选项,被认为已弃用而倾向于其他选项,使用不安全,或者根本不再相关。

  • {cert, Certs}

    请改用选项 certs_keys

  • {certfile, CertPem}

    请改用选项 certs_keys

  • {keyfile, KeyPem}

    请改用选项 certs_keys

  • {password, KeyPemPasswd}

    请改用选项 certs_keys

  • {log_alert, LogAlert}

    如果 LogAlertfalse,则不会显示 TLS/DTLS 警报报告。在 OTP 22 中已弃用;请改用 {log_level, Level}

  • {padding_check, PaddingCheck} - 互操作权衡选项

    仅影响 TLS-1.0 连接。如果设置为 false,它将禁用块密码填充检查,以便能够与旧软件互操作。

    警告

    使用 {padding_check, false} 会使 TLS 容易受到 Poodle 攻击。

  • {beast_mitigation, BeastMitigation} - 互操作权衡选项

    仅影响 TLS-1.0 连接。用于更改 BEAST 缓解策略以与旧软件互操作。默认为 one_n_minus_one

    one_n_minus_one - 执行 1/n-1 BEAST 缓解。

    zero_n - 执行 0/n BEAST 缓解。

    disabled - 禁用 BEAST 缓解。

    警告

    使用 {beast_mitigation, disabled} 会使 TLS-1.0 容易受到 BEAST 攻击。

  • {ssl_imp, Imp}

    自 OTP 17 起已弃用;无效。

链接到此类型

common_option_pre_tls13()

查看源代码 (未导出)
-type common_option_pre_tls13() ::
          {eccs, NamedCurves :: [named_curve()]} |
          {secure_renegotiate, SecureRenegotiate :: boolean()} |
          {user_lookup_fun, {Lookupfun :: fun(), UserState :: any()}}.

TLS-1.3 之前客户端和服务器端通用的选项。

  • {eccs, NamedCurves} - 命名椭圆曲线

    可以在 TLS-1.3 之前的密钥交换中使用的椭圆曲线。

  • {secure_renegotiate, SecureRenegotiate} - 互操作权衡选项

    指定是否拒绝不符合 RFC 5746 的重新协商尝试。默认情况下,SecureRenegotiatetrue,这意味着强制执行安全重新协商。如果 SecureRenegotiatefalse,则如果可能,仍然会使用安全重新协商,但如果对等方不支持 RFC 5746,则会回退到不安全的重新协商。

  • {user_lookup_fun, {LookupFun, UserState}} - PSK/SRP 密码套件选项

    查找函数定义如下

    fun(psk, PSKIdentity :: binary(), UserState :: term()) ->
      {ok, SharedSecret :: binary()} | error;
    fun(srp, Username :: binary(), UserState :: term()) ->
      {ok, {SRPParams :: srp_param_type(), Salt :: binary(),
            DerivedKey :: binary()}} | error.

    对于预共享密钥 (PSK) 密码套件,客户端和服务器都会调用查找函数来确定共享密钥。当客户端调用时,PSKIdentity 是服务器提供的提示或 undefined。当服务器调用时,PSKIdentity 是客户端提供的身份。

    对于安全远程密码 (SRP),该函数仅由服务器用于获取其用于生成会话密钥的参数。DerivedKey 应根据 RFC 2945RFC 5054 派生:crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])])

-type common_option_tls13() ::
          {supported_groups, [group()]} | {key_update_at, KeyUpdateAt :: pos_integer()}.

客户端和服务器都通用的 TLS-1.3 的选项。

  • {supported_groups, Groups} - 密钥交换选项

    TLS 1.3 引入了 "supported_groups" 扩展,用于在 TLS 1.3 握手中协商 Diffie-Hellman 参数。客户端和服务器都可以指定它们愿意使用的参数列表。

    如果未指定,它将使用基于已安装的加密库版本过滤的默认列表 ([x25519, x448, secp256r1, secp384r1])。

  • {key_update_at, KeyUpdateAt} - 会话密钥更新

    配置在执行自动密钥更新之前可以在 TLS 1.3 连接上发送的最大字节数。

    在给定的密钥集下,可以安全加密的明文数量存在密码学限制。当前默认设置确保数据完整性被破坏的概率不大于 1/2^57。有关更多信息,请参阅 TLS 中认证加密使用的限制

类型:信息

-type connection_info() ::
          [{protocol, protocol_version()} |
           {session_resumption, boolean()} |
           {selected_cipher_suite, erl_cipher_suite()} |
           {sni_hostname, term()} |
           {ciphers, [erl_cipher_suite()]}] |
          connection_info_pre_tls13() |
          security_info().

包含有关已建立连接的一些信息的键值列表。

链接到此类型

connection_info_keys()

查看源代码
-type connection_info_keys() ::
          [protocol | selected_cipher_suite | sni_hostname | session_resumption | ciphers |
           client_random | server_random | master_secret | keylog | session_id | session_data | ecc |
           srp_username].

可以检索信息的 TLS 连接密钥。

链接到此类型

connection_info_pre_tls13()

查看源代码 (未导出)
-type connection_info_pre_tls13() ::
          [{session_id, session_id()} |
           {session_data, binary()} |
           {ecc, {named_curve, term()}} |
           {srp_username, term()}].

与 TLS-1.3 之前的版本相关的 TLS 连接信息。

链接到此类型

security_info()

查看源代码 (未导出)
-type security_info() ::
          [{client_random, binary()} |
           {server_random, binary()} |
           {master_secret, binary()} |
           {keylog, term()}].

可用于 NSS 密钥日志记录的 TLS 连接信息。

类型:已弃用

此类型已弃用。类型 ssl:prf_random() 已弃用;仅在已弃用的函数 prf/5 中使用,并且不再需要。
-type prf_random() :: client_random | server_random.

客户端 API

链接到此函数

connect(TCPSocket, TLSOptions)

查看源代码 (自 OTP R14B 起)
-spec connect(TCPSocket, TLSOptions) -> {ok, sslsocket()} | {error, Reason}
                 when
                     TCPSocket :: socket(),
                     TLSOptions :: [tls_client_option()],
                     Reason :: closed | {options, any()} | error_alert() | reason().

等效于 connect(TCPSocket, TLSOptions, infinity)

链接到此函数

connect(TCPSocketOrHost, TLSOptionsOrPort, TimeoutOrTLSOptions)

查看源代码
-spec connect(TCPSocketOrHost, TLSOptionsOrPort, TimeoutOrTLSOptions) ->
                 {ok, sslsocket()} | {ok, sslsocket(), Ext :: protocol_extensions()} | {error, Reason}
                 when
                     TCPSocketOrHost :: socket() | host(),
                     TLSOptionsOrPort :: [tls_client_option()] | inet:port_number(),
                     TimeoutOrTLSOptions :: [tls_client_option()] | timeout(),
                     Reason :: closed | timeout | {options, any()} | error_alert() | reason().

打开 TLS/DTLS 连接。

connect(TCPSocket, TLSOptions, Timeout).

通过执行客户端 TLS 握手,将已连接的 gen_tcp(或等效)套接字升级为 TLS 套接字。

connect(Host, Port, TLSOptions).

打开与 Host, Port 的 TLS/DTLS 连接。此调用等效于

connect(Host, Port, TLSOptions, infinity).
链接到此函数

connect(Host, Port, TLSOptions, Timeout)

查看源代码
-spec connect(Host, Port, TLSOptions, Timeout) ->
                 {ok, sslsocket()} | {ok, sslsocket(), Ext :: protocol_extensions()} | {error, Reason}
                 when
                     Host :: host(),
                     Port :: inet:port_number(),
                     TLSOptions :: [tls_client_option()],
                     Timeout :: timeout(),
                     Reason :: closed | timeout | {options, any()} | error_alert() | reason().

打开到 Host, Port 的 TLS/DTLS 连接。

verify 选项设置为 verify_peer 时,除了通常的 X.509 路径验证检查之外,还将执行 public_key:pkix_verify_hostname/2 检查。如果检查失败,错误 {bad_cert, hostname_check_failed} 将传播到路径验证函数,在那里可以使用 public_key:pkix_verify_hostname/3 API 的全部功能进行自定义检查。当提供 server_name_indication 选项时,其值(DNS 名称)将用作 public_key:pkix_verify_hostname/2ReferenceID。当没有给出 server_name_indication 选项时,Host 参数将用作服务器名称指示扩展。Host 参数还将用于 public_key:pkix_verify_hostname/2 检查。如果 Host 参数是 inet:ip_address(),则用于检查的 ReferenceID 将是 {ip, Host};否则,将假定为 dns_id,如果失败,则回退到 ip

注意

根据良好实践,证书不应使用 IP 地址作为“服务器名称”,尤其是在封闭网络之外。

如果使用 {handshake, hello} 选项,则在收到服务器 hello 消息后,握手会暂停,并且成功响应为 {ok, SslSocket, Ext} 而不是 {ok, SslSocket}。此后,通过调用 handshake_continue/3handshake_cancel/1 继续或取消握手。

如果 active 选项设置为 oncetrue 或整数值,则拥有 SSL 套接字的进程将接收类型为 active_msgs() 的消息。

服务器 API

链接到此函数

handshake(HsSocket)

查看源代码 (自 OTP 21.0 起)
-spec handshake(HsSocket) -> {ok, SslSocket} | {ok, SslSocket, Ext} | {error, Reason}
                   when
                       HsSocket :: sslsocket(),
                       SslSocket :: sslsocket(),
                       Ext :: protocol_extensions(),
                       Reason :: closed | timeout | error_alert().

等效于 handshake(HsSocket, infinity)

链接到此函数

handshake(HsSocket, OptionsOrTimeout)

查看源代码 (自 OTP 21.0 起)
-spec handshake(HsSocket, OptionsOrTimeout) -> {ok, SslSocket} | {ok, SslSocket, Ext} | {error, Reason}
                   when
                       HsSocket :: sslsocket(),
                       OptionsOrTimeout :: timeout() | [server_option()],
                       SslSocket :: sslsocket(),
                       Ext :: protocol_extensions(),
                       Reason :: closed | timeout | error_alert().

执行 TLS/DTLS 服务器端握手。

如果第二个参数是超时值

handshake(HsSocket, Timeout).

则此调用等效于

handshake(HsSocket, [], Timeout).

否则,如果第二个参数是选项列表

handshake(HsSocket, Options).

则此调用等效于

handshake(HsSocket, Options, infinity).
链接到此函数

handshake(Socket, Options, Timeout)

查看源代码 (自 OTP 21.0 起)
-spec handshake(Socket, Options, Timeout) -> {ok, SslSocket} | {ok, SslSocket, Ext} | {error, Reason}
                   when
                       Socket :: socket() | sslsocket(),
                       SslSocket :: sslsocket(),
                       Options :: [server_option()],
                       Timeout :: timeout(),
                       Ext :: protocol_extensions(),
                       Reason :: closed | timeout | {options, any()} | error_alert().

执行 TLS/DTLS 服务器端握手。

如果握手成功,则返回新的 TLS/DTLS 套接字。

如果 Socket 是普通的 socket(),则通过执行 TLS 服务器端握手并将返回的套接字升级为 TLS 套接字,将 gen_tcp 或等效套接字升级为 SSL 套接字。

注意

在调用此函数之前,以及客户端尝试使用 TLS 连接之前,普通 Socket 必须处于被动模式 ({active, false});否则,此函数的行为是未定义的。确保这一点的最佳方法是在被动模式下创建普通的侦听套接字。

如果 Socketsslsocket(),则向 listen/2 中指定的套接字提供额外的 TLS/DTLS 选项,然后执行 TLS/DTLS 握手。如果握手成功,则返回新的 TLS/DTLS 套接字。

警告

不设置超时会使服务器更容易受到拒绝服务 (DoS) 攻击。

如果指定了选项 {handshake, hello},则在收到客户端 hello 消息后,握手会暂停,并且成功响应为 {ok, SslSocket, Ext} 而不是 {ok, SslSocket}。此后,通过调用 handshake_continue/3handshake_cancel/1 继续或取消握手。

如果选项 active 设置为 oncetrue 或整数值,则拥有 sslsocket() 的进程将接收类型为 active_msgs() 的消息。

-spec listen(Port, Options) -> {ok, ListenSocket} | {error, Reason}
                when
                    Port :: inet:port_number(),
                    Options :: [tls_server_option()],
                    ListenSocket :: sslsocket(),
                    Reason :: {options, any()} | reason().

创建 SSL 监听套接字。

链接到此函数

transport_accept(ListenSocket)

查看源代码
-spec transport_accept(ListenSocket) -> {ok, SslSocket} | {error, Reason}
                          when ListenSocket :: sslsocket(), SslSocket :: sslsocket(), Reason :: reason().

等效于 transport_accept(ListenSocket, infinity)

链接到此函数

transport_accept(ListenSocket, Timeout)

查看源代码
-spec transport_accept(ListenSocket, Timeout) -> {ok, SslSocket} | {error, Reason}
                          when
                              ListenSocket :: sslsocket(),
                              Timeout :: timeout(),
                              SslSocket :: sslsocket(),
                              Reason :: reason().

接受监听套接字上的传入连接请求。

ListenSocket 必须是从 listen/2 返回的套接字。返回的套接字将传递给 handshake/1,2,3 以完成握手并建立 TLS/DTLS 连接。

警告

大多数 API 函数要求建立 TLS/DTLS 连接才能按预期工作。

接受的套接字继承了在 listen/2 中为 ListenSocket 设置的选项。

Timeout 的默认值为 infinity。如果指定了 Timeout,并且在给定的时间内未接受任何连接,则返回 {error, timeout}

客户端和服务器 API

-spec close(SslSocket) -> ok | {error, Reason} when SslSocket :: sslsocket(), Reason :: any().

关闭 TLS/DTLS 连接。

链接到此函数

close(SslSocket, How)

查看源代码 (自 OTP 18.1 起)
-spec close(SslSocket, How) -> ok | {ok, port()} | {ok, port(), Data} | {error, Reason}
               when
                   SslSocket :: sslsocket(),
                   How :: timeout() | {NewController :: pid(), timeout()},
                   Data :: binary(),
                   Reason :: any().

关闭或降级 TLS 连接。

在后一种情况下,在收到来自对端的 TLS 关闭警报后,传输连接将移交给 NewController 进程。返回的传输套接字将设置以下选项:[{active, false}, {packet, 0}, {mode, binary}]

在降级的情况下,关闭函数可能会返回一些二进制数据,用户应将其视为降级连接上收到的第一个字节。

链接到此函数

controlling_process(SslSocket, NewOwner)

查看源代码
-spec controlling_process(SslSocket, NewOwner) -> ok | {error, Reason}
                             when SslSocket :: sslsocket(), NewOwner :: pid(), Reason :: any().

为 SSL 套接字分配新的控制进程。

控制进程是 SSL 套接字的所有者,并接收来自套接字的所有消息。

链接到此函数

handshake_cancel(Socket)

查看源代码 (自 OTP 21.0 起)
-spec handshake_cancel(#sslsocket{fd :: term(), pid :: term()}) -> any().

使用致命的 USER_CANCELED 警报取消握手。

链接到此函数

handshake_continue(HsSocket, Options)

查看源代码 (自 OTP 21.0 起)
-spec handshake_continue(HsSocket, Options) -> {ok, SslSocket} | {error, Reason}
                            when
                                HsSocket :: sslsocket(),
                                Options :: [tls_client_option() | tls_server_option()],
                                SslSocket :: sslsocket(),
                                Reason :: closed | timeout | error_alert().

等效于 handshake_continue(HsSocket, Options, infinity)

链接到此函数

handshake_continue(HsSocket, Options, Timeout)

查看源代码 (自 OTP 21.0 起)
-spec handshake_continue(HsSocket, Options, Timeout) -> {ok, SslSocket} | {error, Reason}
                            when
                                HsSocket :: sslsocket(),
                                Options :: [tls_client_option() | tls_server_option()],
                                Timeout :: timeout(),
                                SslSocket :: sslsocket(),
                                Reason :: closed | timeout | error_alert().

继续 TLS 握手,可能使用新的、附加的或更改的选项。

链接到此函数

recv(SslSocket, Length)

查看源代码
-spec recv(SslSocket, Length) -> {ok, Data} | {error, reason()}
              when
                  SslSocket :: sslsocket(),
                  Length :: non_neg_integer(),
                  Data :: binary() | list() | HttpPacket,
                  HttpPacket :: any().

等效于 recv(Socket, Length, infinity)

链接到此函数

recv(SslSocket, Length, Timeout)

查看源代码
-spec recv(SslSocket, Length, Timeout) -> {ok, Data} | {error, reason()}
              when
                  SslSocket :: sslsocket(),
                  Length :: non_neg_integer(),
                  Data :: binary() | list() | HttpPacket,
                  Timeout :: timeout(),
                  HttpPacket :: any().

以被动模式从套接字接收数据包。

返回值 {error, closed} 表示套接字已关闭。仅当套接字处于 raw 模式时,参数 Length 才有意义,表示要读取的字节数。如果 Length 为零,则返回所有可用字节。如果 Length 大于零,则返回正好 Length 个字节,或者返回错误;当套接字从另一侧关闭时,可能会丢弃少于 Length 个字节的数据。

可选参数 Timeout 指定以毫秒为单位的超时时间。默认值为 infinity

-spec send(SslSocket, Data) -> ok | {error, reason()} when SslSocket :: sslsocket(), Data :: iodata().

Data 写入 SslSocket

一个值得注意的返回值是 {error, closed},表示套接字已关闭。

链接到此函数

setopts(SslSocket, Options)

查看源代码
-spec setopts(SslSocket, Options) -> ok | {error, reason()}
                 when SslSocket :: sslsocket(), Options :: [gen_tcp:option()].

根据套接字 SslSocketOptions 设置选项。

链接到此函数

shutdown(SslSocket, How)

查看源代码 (自 OTP R14B 起)
-spec shutdown(SslSocket, How) -> ok | {error, reason()}
                  when SslSocket :: sslsocket(), How :: read | write | read_write.

立即在一个或两个方向关闭套接字。

How == write 表示关闭套接字的写入端,但仍然可以从中读取数据。

为了处理对等方已关闭写入端的情况,可以使用选项 {exit_on_close, false}

仅限 TLS-1.3 API

链接到此函数

groups()

查看源代码 (自 OTP 27.0 起)
-spec groups() -> [group()].

返回 TLS 1.3 中所有受支持的组。

自 OTP 22.0 起存在;从 OTP 27 开始记录。

链接到此函数

groups(Description)

查看源代码 (自 OTP 27.0 起)
-spec groups(Description) -> [group()] when Description :: default.

返回 TLS 1.3 中默认支持的组。

自 OTP 22.0 起存在;从 OTP 27 开始记录。

链接到此函数

update_keys(SslSocket, Type)

查看源代码 (自 OTP 22.3 起)
-spec update_keys(SslSocket, Type) -> ok | {error, reason()}
                     when SslSocket :: sslsocket(), Type :: write | read_write.

创建新的会话密钥。

在给定的密钥集下,可以安全加密的明文量存在密码学限制。如果数据量超过这些限制,将触发密钥更新并安装新的密钥集。另请参见 common_option_tls13/0 中的 key_update_at 选项。

此函数可用于在 TLS-1.3 连接上显式启动密钥更新。密钥更新有两种类型:如果 Typewrite,则仅更新写入密钥;如果 Typeread_write,则更新读取和写入密钥。

TLS-1.3 之前的 API

链接到此函数

eccs()

查看源代码 (自 OTP 19.2 起)
-spec eccs() -> NamedCurves when NamedCurves :: [named_curve()].

返回所有受支持的椭圆曲线的列表,包括 TLS-1.3 之前的所有 TLS/DTLS 版本的旧版曲线。

链接到此函数

eccs(Version)

查看源代码 (自 OTP 19.2 起)
-spec eccs(Version) -> NamedCurves
              when
                  Version :: 'tlsv1.2' | 'tlsv1.1' | tlsv1 | 'dtlsv1.2' | dtlsv1,
                  NamedCurves :: [named_curve()].

返回 Version 默认支持的椭圆曲线。

这是 eccs/0 返回值的一个子集。

链接到此函数

renegotiate(SslSocket)

查看源代码 (自 OTP R14B 起)
-spec renegotiate(SslSocket) -> ok | {error, reason()} when SslSocket :: sslsocket().

启动新的握手。

一个值得注意的返回值是 {error, renegotiation_rejected},表示对等方拒绝进行重新协商,但连接仍然使用先前协商的会话保持活动状态。

TLS-1.3 从较早的 TLS 版本中删除了重新协商功能,而是添加了一个名为密钥更新的新功能,该功能取代了重新协商的最重要部分:刷新会话密钥。这会在达到明文限制后自动触发,并且可以使用 common_option_tls13/0 中的 key_update_at 选项进行配置。

实用函数

链接到此函数

append_cipher_suites(Deferred, Suites)

查看源代码 (自 OTP 20.3 起)
-spec append_cipher_suites(Deferred, Suites) -> ciphers()
                              when Deferred :: ciphers() | cipher_filters(), Suites :: ciphers().

使 Deferred 套件成为最不首选的套件。

如果 Deferred 套件存在于 Suites 列表中,则将其从 Suites 中删除后,将其放置在密码套件列表 Suites 的末尾。Deferred 可以是密码套件列表,也可以是过滤器列表,在这种情况下,将对 Suites 使用过滤器以提取延迟密码列表。

链接到此函数

cipher_suites(Description, Version)

查看源代码 (自 OTP 20.3 起)
-spec cipher_suites(Description, Version) -> ciphers()
                       when
                           Description :: default | all | exclusive | anonymous | exclusive_anonymous,
                           Version :: protocol_version().

列出与 Description 对应的所有可用密码套件。

exclusiveexclusive_anonymous 选项将专门列出 Version 中首次支持的密码套件,而其他选项则包含从最低可能版本到 Version 的所有密码套件。all 选项包括除匿名套件外的所有套件。默认情况下不支持任何匿名套件。

注意

TLS-1.3 与之前的 TLS 版本没有重叠的密码套件,这意味着 cipher_suites(all, 'tlsv1.3') 的结果包含一个可以与 TLS-1.3 一起使用的单独套件集,以及另一个可以在协商较低版本时使用的套件集。所谓的 PSKSRP 套件(在 TLS-1.3 之前)需要额外的配置才能工作;即选项 user_lookup_function。TLS-1.3 不支持任何匿名套件。

另请注意,此函数返回的密码套件是 OTP SSL 应用程序可以支持的密码套件,前提是它们受与 OTP Crypto 应用程序链接的加密库支持。使用 ssl:filter_cipher_suites(Suites, []) 来筛选当前加密库的列表。请注意,根据加密库的不同,密码套件可能会因过旧或过新而被过滤掉。

链接到此函数

cipher_suites(Description, Version, StringType)

查看源代码 (自 OTP 22.0 起)
-spec cipher_suites(Description, Version, StringType) -> [string()]
                       when
                           Description :: default | all | exclusive | anonymous,
                           Version :: protocol_version(),
                           StringType :: rfc | openssl.

等效于 cipher_suites/2,但列出 RFC 或 OpenSSL 字符串名称,而不是 erl_cipher_suite()

链接到此函数

clear_pem_cache()

查看源代码 (自 OTP 17.5 起)
-spec clear_pem_cache() -> ok.

清除 PEM 缓存。

出于性能原因,SSL API 函数使用的 PEM 文件会被缓存。缓存会定期自动检查,以确定是否应使任何缓存条目失效。

此函数提供了一种无条件清除整个缓存的方法,从而强制重新加载先前缓存的 PEM 文件。

链接到此函数

connection_information(SslSocket)

查看源代码 (自 OTP 18.0 起)
-spec connection_information(SslSocket) -> {ok, Result} | {error, reason()}
                                when SslSocket :: sslsocket(), Result :: connection_info().

返回有关连接的最相关信息。

一些未定义的项目将被过滤掉。不会返回任何影响连接安全性的值。

注意

旧的 cipher_suite 项已在 OTP 23 中删除。之前,它以其(未记录的)旧格式返回密码套件。它已被 selected_cipher_suite 取代。

链接到此函数

connection_information(SslSocket, Items)

查看源代码 (自 OTP 18.0 起)
-spec connection_information(SslSocket, Items) -> {ok, Result} | {error, reason()}
                                when
                                    SslSocket :: sslsocket(),
                                    Items :: connection_info_keys(),
                                    Result :: connection_info().

如果已定义,则返回有关连接的请求信息项。

请注意,client_randomserver_randommaster_secretkeylog 的值会影响连接的安全性。

为了从 TLS 1.3 连接中检索 keylog 和其他机密信息,必须提前配置 keep_secrets 选项并将其设置为 true

注意

如果仅请求未定义的选项,则结果列表可能为空。

链接到此函数

export_key_materials(SslSocket, Labels, Contexts, WantedLengths)

查看源代码 (自 OTP 27.0 起)
-spec export_key_materials(SslSocket, Labels, Contexts, WantedLengths) ->
                              {ok, ExportKeyMaterials} | {error, reason()}
                              when
                                  SslSocket :: sslsocket(),
                                  Labels :: [binary()],
                                  Contexts :: [binary() | no_context],
                                  WantedLengths :: [non_neg_integer()],
                                  ExportKeyMaterials :: [binary()].

等效于 export_key_materials(TLSSocket, Labels, Contexts, WantedLengths, true)

链接到此函数

export_key_materials(SslSocket, Labels, Contexts, WantedLengths, ConsumeSecret)

查看源代码 (自 OTP 27.0 起)
-spec export_key_materials(SslSocket, Labels, Contexts, WantedLengths, ConsumeSecret) ->
                              {ok, ExportKeyMaterials} |
                              {error, exporter_master_secret_already_consumed | bad_input}
                              when
                                  SslSocket :: sslsocket(),
                                  Labels :: [binary()],
                                  Contexts :: [binary() | no_context],
                                  WantedLengths :: [non_neg_integer()],
                                  ConsumeSecret :: boolean(),
                                  ExportKeyMaterials :: [binary()].

使用伪随机函数 (TLS-1.3 之前的 PRF) 或密钥派生函数 (TLS-1.3 中的 HKDF) 进行 TLS 连接,以生成和导出密钥材料。

在 TLS-1.3 中,使用 no_context 等同于指定空上下文(空二进制)。在 TLS-1.3 之前,no_context 和空上下文会产生不同的结果。

ConsumeSecret 参数仅在 TLS-1.3 中相关,导致 TLS-1.3 exporter_master_secret 被消耗掉,从而使其不可用并提高了安全性。进一步调用此函数的尝试将失败。

链接到此函数

filter_cipher_suites(Suites, Filters)

查看源代码 (自 OTP 20.3 起)
-spec filter_cipher_suites(Suites, Filters) -> Ciphers
                              when
                                  Suites :: ciphers(), Filters :: cipher_filters(), Ciphers :: ciphers().

如果任何过滤器函数对密码套件的任何部分返回 false,则删除密码套件。

如果没有为某些部分提供过滤器函数,则默认行为将其视为返回 true 的过滤器函数。有关示例,请参见自定义密码套件。此外,此函数还会过滤密码套件,以排除 OTP Crypto 应用程序使用的加密库不支持的密码套件,这意味着 ssl:filter_cipher_suites(Suites, []) 等效于仅应用加密库支持的过滤器。

-spec format_error(Error) -> ReasonStr when Error :: {error, reason()} | reason(), ReasonStr :: string().

将 SSL 函数返回的错误显示为可打印的字符串。

链接到此函数

getopts(SslSocket, OptionNames)

查看源代码
-spec getopts(SslSocket, OptionNames) -> {ok, [gen_tcp:option()]} | {error, reason()}
                 when SslSocket :: sslsocket(), OptionNames :: [gen_tcp:option_name()].

获取指定套接字选项的值。

链接到此函数

getstat(SslSocket)

查看源代码 (自 OTP 19.0 起)
-spec getstat(SslSocket) -> {ok, OptionValues} | {error, inet:posix()}
                 when SslSocket :: sslsocket(), OptionValues :: [{inet:stat_option(), integer()}].

获取底层套接字的统计信息。

链接到此函数

getstat(SslSocket, Options)

查看源代码 (自 OTP 19.0 起)
-spec getstat(SslSocket, Options) -> {ok, OptionValues} | {error, inet:posix()}
                 when
                     SslSocket :: sslsocket(),
                     Options :: [inet:stat_option()],
                     OptionValues :: [{inet:stat_option(), integer()}].

获取底层套接的一个或多个统计值。

有关更多详细信息,请参见 inet:getstat/2

链接到此函数

negotiated_protocol(SslSocket)

查看源代码 (自 OTP 18.0 起)
-spec negotiated_protocol(SslSocket) -> {ok, Protocol} | {error, Reason}
                             when
                                 SslSocket :: sslsocket(),
                                 Protocol :: binary(),
                                 Reason :: protocol_not_negotiated | closed.

返回通过 ALPN 或 NPN 扩展协商的协议。

-spec peercert(SslSocket) -> {ok, Cert} | {error, reason()}
                  when SslSocket :: sslsocket(), Cert :: public_key:der_encoded().

对等证书以 DER 编码的二进制形式返回。

可以使用 public_key:pkix_decode_cert/2 解码证书。有关证书的更多建议阅读内容是 Public_Key 用户指南SSL 用户指南

-spec peername(SslSocket) -> {ok, {Address, Port}} | {error, reason()}
                  when
                      SslSocket :: sslsocket(), Address :: inet:ip_address(), Port :: inet:port_number().

返回对等方的地址和端口号。

链接到此函数

prepend_cipher_suites(Preferred, Suites)

查看源代码 (自 OTP 20.3 起)
-spec prepend_cipher_suites(Preferred, Suites) -> ciphers()
                               when Preferred :: ciphers() | cipher_filters(), Suites :: ciphers().

使 Preferred 套件成为最首选的套件。

如果 Preferred 套件存在于 Suites 列表中,则将其从 Suites 中删除后,将其放置在密码套件列表 Suites 的开头。Preferred 可以是密码套件列表,也可以是过滤器列表,在这种情况下,将对 Suites 使用过滤器以提取首选密码列表。

链接到此函数

signature_algs(Description, Version)

查看源代码 (自 OTP 26.0 起)
-spec signature_algs(Description, Version) -> signature_algs()
                        when Description :: default | all | exclusive, Version :: protocol_version().

列出与 Description 对应的所有可用签名算法。

exclusive 选项将为该协议版本独占列出算法或算法方案,而 defaultall 选项则列出组合列表,以支持从 (D)TLS-1.2(第一个支持签名算法配置的版本)到 Version 的协议范围。

示例

1> ssl:signature_algs(default, 'tlsv1.3').
[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,
rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,
rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,
rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256,
{sha512,ecdsa},
{sha384,ecdsa},
{sha256,ecdsa}]

2> ssl:signature_algs(all, 'tlsv1.3').
[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,
rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,
rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,
rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256,
{sha512,ecdsa},
{sha384,ecdsa},
{sha256,ecdsa},
{sha224,ecdsa},
{sha224,rsa},
{sha,rsa},
{sha,dsa}]

3> ssl:signature_algs(exclusive, 'tlsv1.3').
[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,
rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,
rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256]

注意

一些 TLS-1.3 方案名称与 TLS-1.2 算法-元组-对名称重叠,然后将使用 TLS-1.3 名称,例如 rsa_pkcs1_sha256 而不是 {sha256, rsa}。这些是 TLS-1.3 中的遗留算法,仅适用于此协议版本的证书签名。

-spec sockname(SslSocket) -> {ok, {Address, Port}} | {error, reason()}
                  when
                      SslSocket :: sslsocket(), Address :: inet:ip_address(), Port :: inet:port_number().

返回套接字 SslSocket 的本地地址和端口号。

链接到此函数

start()

查看源代码 (自 OTP R14B 起)
-spec start() -> ok | {error, reason()}.

等效于 start(temporary)

链接到此函数

start(Type)

查看源代码 (自 OTP R14B 起)
-spec start(permanent | transient | temporary) -> ok | {error, reason()}.

启动 SSL 应用程序。

链接到此函数

stop()

查看源代码 (自 OTP R14B 起)
-spec stop() -> ok.

停止 SSL 应用程序。

链接到此函数

str_to_suite(CipherSuiteName)

查看源代码 (自 OTP 22.0 起)
-spec str_to_suite(CipherSuiteName) -> erl_cipher_suite() | {error, {not_recognized, CipherSuiteName}}
                      when CipherSuiteName :: string().

将 RFC 或 OpenSSL 名称字符串转换为 erl_cipher_suite/0

如果不支持该密码套件或名称不是有效的密码套件名称,则返回错误。

链接到此函数

suite_to_openssl_str(CipherSuite)

查看源代码 (自 OTP 22.0 起)
-spec suite_to_openssl_str(CipherSuite) -> string() when CipherSuite :: erl_cipher_suite().

erl_cipher_suite() 值转换为 OpenSSL 名称字符串。

在 TLS-1.3 之前,这些名称与 RFC 名称不同。

链接到此函数

suite_to_str(CipherSuite)

查看源代码 (自 OTP 21.0 起)
-spec suite_to_str(CipherSuite) -> string() when CipherSuite :: erl_cipher_suite().

erl_cipher_suite() 值转换为 RFC 名称字符串。

链接到此函数

versions()

查看源代码 (自 OTP R14B 起)
-spec versions() -> [VersionInfo]
                  when
                      VersionInfo ::
                          {ssl_app, string()} |
                          {supported | available | implemented, [tls_version()]} |
                          {supported_dtls | available_dtls | implemented_dtls, [dtls_version()]}.

列出运行时信息,主要涉及 TLS/DTLS 版本,用于调试和测试目的。

  • app_vsn - SSL 应用程序的版本。

  • supported - 当前应用程序环境和加密库配置支持的 TLS 版本。被 connect/2,3,4listen/2handshake/2,3 上的 version 选项覆盖。 对于协商的 TLS 版本,请参阅 connection_information/1

  • supported_dtls - 当前应用程序环境和加密库配置支持的 DTLS 版本。被 connect/2,3,4listen/2handshake/2,3 上的 version 选项覆盖。 对于协商的 DTLS 版本,请参阅 connection_information/1

  • available - 链接的加密库支持的所有 TLS 版本。

  • available_dtls - 链接的加密库支持的所有 DTLS 版本。

  • implemented - 如果与具有必要支持的加密库链接,则 SSL 应用程序支持的所有 TLS 版本。

  • implemented_dtls - 如果与具有必要支持的加密库链接,则 SSL 应用程序支持的所有 DTLS 版本。

已弃用的 API

链接到此函数

prf(SslSocket, Secret, Label, Seed, WantedLength)

查看源代码 (自 OTP R15B01 起)
此函数已弃用。ssl:prf/5 已弃用;请改用 export_key_materials/4。请注意,在 OTP 28 中,将不再支持调用此函数的“测试”方式。
-spec prf(SslSocket, Secret, Label, Seed, WantedLength) -> {ok, binary()} | {error, reason()}
             when
                 SslSocket :: sslsocket(),
                 Secret :: binary() | master_secret,
                 Label :: binary(),
                 Seed :: [binary() | prf_random()],
                 WantedLength :: non_neg_integer().

使用 TLS 会话的伪随机函数 (PRF) 生成额外的密钥材料。

它要么采用用户生成的 SecretSeed 值,要么采用原子来指示其使用会话安全参数中的特定值。

注意

此函数已被 export_key_materials/4 替换,后者是自 OTP 27 以来的官方文档 API 函数,相当于 prf(TLSSocket, master_secret, Label, [client_random, server_random, Context], WantedLength)。调用此函数的其他方式仅用于测试目的,没有用例。在 TLS-1.3 上下文中调用时,它现在的行为将类似于 export_key_materials(TLSSocket, [Label], [Context], [WantedLength])