查看源代码 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 密码套件配置。
类型:算法(旧版)
出于安全原因,默认情况下不再支持的密码算法。
出于安全原因,默认情况下不再支持的哈希算法。
TLS-1.3 之前的密钥交换配置。
出于安全原因,默认情况下不再支持的签名算法。
如果协商 TLS-1.2,这仅用于证书签名,这意味着对等方仅支持 TLS-1.2,但我们也支持 TLS-1.3。
仅用于向后兼容性;请勿使用。
类型:已弃用
客户端和服务器 API
关闭 TLS/DTLS 连接。
关闭或降级 TLS 连接。
为 SSL 套接字分配新的控制进程。
使用致命的 USER_CANCELED
警报取消握手。
继续 TLS 握手,可能使用新的、附加的或更改的选项。
以被动模式从套接字接收数据包。
将 Data
写入 SslSocket
。
根据套接字 SslSocket
的 Options
设置选项。
立即在一个或两个方向关闭套接字。
实用函数
使 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}
) 模式。
-type dtls_legacy_version() :: dtlsv1.
出于安全原因,默认情况下不再支持的 DTLS 协议版本。
-type dtls_version() :: 'dtlsv1.2' | dtls_legacy_version().
DTLS 协议版本。
如果 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 中的 inet
、gen_tcp
和 gen_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 客户端的选项。
-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 服务器的选项。
-type tls_version() :: 'tlsv1.2' | 'tlsv1.3' | tls_legacy_version().
TLS 协议版本。
-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
是附加了_passive
的DataTag
元素。
对于 TLS,回调模块必须实现可靠的传输协议,其行为类似于 gen_tcp
,并且具有与 inet:setopts/2
、inet:getopts/2
、inet:peername/1
、inet:sockname/1
和 inet: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)}].
允许您自定义密码套件列表的过滤器。
-type cipher_suites() :: ciphers().
应支持的密码套件列表。
函数 ssl:cipher_suites/2 可用于查找默认支持的所有密码套件以及可以配置的所有密码套件。
如果你组合自己的 cipher_suites/0
,请确保使用 ssl:filter_cipher_suites/2 对它们进行加密库支持的过滤。
以下函数可以帮助创建自定义的密码套件列表
- ssl:append_cipher_suites/2
- ssl:prepend_cipher_suites/2
- ssl:suite_to_str/1
- ssl:str_to_suite/1
- ssl:suite_to_openssl_str/1
注意
请注意,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 之前的密钥交换配置。
-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 密码套件配置。
类型:证书
-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 缓存支持的选项。
指定如何执行证书吊销列表 (CRL) 的查找和缓存。Module
默认为 ssl_crl_cache
,DbHandle
为 internal
,Args
为 []
。
有两种可用的实现
ssl_crl_cache
- 实现 1此模块维护 CRL 的缓存。可以使用
ssl_crl_cache:insert/1
将 CRL 添加到缓存中,如果指定以下参数,则可以选择通过 HTTP 自动获取 CRL{http, timeout()}
启用获取在 X.509 证书扩展中指定为 http URI 的 CRL。需要 Inets 应用程序。
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) 进行自定义签名。
- DER 编码的密钥需要指定用于创建编码的 ASN-1 类型。
- 引擎/提供程序需要指定特定信息以支持此概念,并且可以选择使用密码保护;另请参阅 crypto:engine_load/3 和 Crypto 用户指南。
- fun 选项应包含一个模仿
public_key:sign/4
的 fun,如果必须支持旧版本的 TLS-1.0 和 TLS-1.1,则可能还包含 public_key:private_encrypt/4。
类型:算法(旧版)
-type legacy_cipher() :: '3des_ede_cbc' | des_cbc | rc4_128.
出于安全原因,默认情况下不再支持的密码算法。
-type legacy_hash() :: sha224 | sha | md5.
出于安全原因,默认情况下不再支持的哈希算法。
-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 弃用。
-type legacy_sign_algo() :: dsa.
出于安全原因,默认情况下不再支持的签名算法。
-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()}.
仅用于向后兼容性;请勿使用。
类型:客户端选项
类型:服务器选项
类型:客户端和服务器选项
类型:信息
-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().
包含有关已建立连接的一些信息的键值列表。
-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 连接密钥。
-type connection_info_pre_tls13() :: [{session_id, session_id()} | {session_data, binary()} | {ecc, {named_curve, term()}} | {srp_username, term()}].
与 TLS-1.3 之前的版本相关的 TLS 连接信息。
-type security_info() :: [{client_random, binary()} | {server_random, binary()} | {master_secret, binary()} | {keylog, term()}].
可用于 NSS 密钥日志记录的 TLS 连接信息。
类型:已弃用
客户端 API
-spec connect(TCPSocket, TLSOptions) -> {ok, sslsocket()} | {error, Reason} when TCPSocket :: socket(), TLSOptions :: [tls_client_option()], Reason :: closed | {options, any()} | error_alert() | reason().
-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).
-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/2
的 ReferenceID
。当没有给出 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/3
或 handshake_cancel/1
继续或取消握手。
如果 active
选项设置为 once
、true
或整数值,则拥有 SSL 套接字的进程将接收类型为 active_msgs()
的消息。
服务器 API
-spec handshake(HsSocket) -> {ok, SslSocket} | {ok, SslSocket, Ext} | {error, Reason} when HsSocket :: sslsocket(), SslSocket :: sslsocket(), Ext :: protocol_extensions(), Reason :: closed | timeout | error_alert().
-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).
-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}
);否则,此函数的行为是未定义的。确保这一点的最佳方法是在被动模式下创建普通的侦听套接字。
如果 Socket
是 sslsocket()
,则向 listen/2
中指定的套接字提供额外的 TLS/DTLS 选项,然后执行 TLS/DTLS 握手。如果握手成功,则返回新的 TLS/DTLS 套接字。
警告
不设置超时会使服务器更容易受到拒绝服务 (DoS) 攻击。
如果指定了选项 {handshake, hello}
,则在收到客户端 hello 消息后,握手会暂停,并且成功响应为 {ok, SslSocket, Ext}
而不是 {ok, SslSocket}
。此后,通过调用 handshake_continue/3
或 handshake_cancel/1
继续或取消握手。
如果选项 active
设置为 once
、true
或整数值,则拥有 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 监听套接字。
-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
关闭 TLS/DTLS 连接。
-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}]
。
在降级的情况下,关闭函数可能会返回一些二进制数据,用户应将其视为降级连接上收到的第一个字节。
-spec controlling_process(SslSocket, NewOwner) -> ok | {error, Reason} when SslSocket :: sslsocket(), NewOwner :: pid(), Reason :: any().
为 SSL 套接字分配新的控制进程。
控制进程是 SSL 套接字的所有者,并接收来自套接字的所有消息。
使用致命的 USER_CANCELED
警报取消握手。
-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().
-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 握手,可能使用新的、附加的或更改的选项。
-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}
,表示套接字已关闭。
-spec setopts(SslSocket, Options) -> ok | {error, reason()} when SslSocket :: sslsocket(), Options :: [gen_tcp:option()].
根据套接字 SslSocket
的 Options
设置选项。
-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
-spec groups() -> [group()].
返回 TLS 1.3 中所有受支持的组。
自 OTP 22.0 起存在;从 OTP 27 开始记录。
-spec groups(Description) -> [group()] when Description :: default.
返回 TLS 1.3 中默认支持的组。
自 OTP 22.0 起存在;从 OTP 27 开始记录。
-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 连接上显式启动密钥更新。密钥更新有两种类型:如果 Type
是 write
,则仅更新写入密钥;如果 Type
是 read_write
,则更新读取和写入密钥。
TLS-1.3 之前的 API
-spec eccs() -> NamedCurves when NamedCurves :: [named_curve()].
返回所有受支持的椭圆曲线的列表,包括 TLS-1.3 之前的所有 TLS/DTLS 版本的旧版曲线。
-spec eccs(Version) -> NamedCurves when Version :: 'tlsv1.2' | 'tlsv1.1' | tlsv1 | 'dtlsv1.2' | dtlsv1, NamedCurves :: [named_curve()].
返回 Version
默认支持的椭圆曲线。
这是 eccs/0
返回值的一个子集。
启动新的握手。
一个值得注意的返回值是 {error, renegotiation_rejected}
,表示对等方拒绝进行重新协商,但连接仍然使用先前协商的会话保持活动状态。
TLS-1.3 从较早的 TLS 版本中删除了重新协商功能,而是添加了一个名为密钥更新的新功能,该功能取代了重新协商的最重要部分:刷新会话密钥。这会在达到明文限制后自动触发,并且可以使用 common_option_tls13/0
中的 key_update_at
选项进行配置。
实用函数
-spec append_cipher_suites(Deferred, Suites) -> ciphers() when Deferred :: ciphers() | cipher_filters(), Suites :: ciphers().
使 Deferred
套件成为最不首选的套件。
如果 Deferred
套件存在于 Suites
列表中,则将其从 Suites
中删除后,将其放置在密码套件列表 Suites
的末尾。Deferred
可以是密码套件列表,也可以是过滤器列表,在这种情况下,将对 Suites
使用过滤器以提取延迟密码列表。
-spec cipher_suites(Description, Version) -> ciphers() when Description :: default | all | exclusive | anonymous | exclusive_anonymous, Version :: protocol_version().
列出与 Description
对应的所有可用密码套件。
exclusive
和 exclusive_anonymous
选项将专门列出 Version
中首次支持的密码套件,而其他选项则包含从最低可能版本到 Version
的所有密码套件。all
选项包括除匿名套件外的所有套件。默认情况下不支持任何匿名套件。
注意
TLS-1.3 与之前的 TLS 版本没有重叠的密码套件,这意味着
cipher_suites(all, 'tlsv1.3')
的结果包含一个可以与 TLS-1.3 一起使用的单独套件集,以及另一个可以在协商较低版本时使用的套件集。所谓的PSK
和SRP
套件(在 TLS-1.3 之前)需要额外的配置才能工作;即选项user_lookup_function
。TLS-1.3 不支持任何匿名套件。另请注意,此函数返回的密码套件是 OTP SSL 应用程序可以支持的密码套件,前提是它们受与 OTP Crypto 应用程序链接的加密库支持。使用
ssl:filter_cipher_suites(Suites, [])
来筛选当前加密库的列表。请注意,根据加密库的不同,密码套件可能会因过旧或过新而被过滤掉。
-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()
。
-spec clear_pem_cache() -> ok.
清除 PEM 缓存。
出于性能原因,SSL API 函数使用的 PEM 文件会被缓存。缓存会定期自动检查,以确定是否应使任何缓存条目失效。
此函数提供了一种无条件清除整个缓存的方法,从而强制重新加载先前缓存的 PEM 文件。
-spec connection_information(SslSocket) -> {ok, Result} | {error, reason()} when SslSocket :: sslsocket(), Result :: connection_info().
返回有关连接的最相关信息。
一些未定义的项目将被过滤掉。不会返回任何影响连接安全性的值。
注意
旧的
cipher_suite
项已在 OTP 23 中删除。之前,它以其(未记录的)旧格式返回密码套件。它已被selected_cipher_suite
取代。
-spec connection_information(SslSocket, Items) -> {ok, Result} | {error, reason()} when SslSocket :: sslsocket(), Items :: connection_info_keys(), Result :: connection_info().
如果已定义,则返回有关连接的请求信息项。
请注意,client_random
、server_random
、master_secret
和 keylog
的值会影响连接的安全性。
为了从 TLS 1.3 连接中检索 keylog
和其他机密信息,必须提前配置 keep_secrets
选项并将其设置为 true
。
注意
如果仅请求未定义的选项,则结果列表可能为空。
-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
被消耗掉,从而使其不可用并提高了安全性。进一步调用此函数的尝试将失败。
-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 函数返回的错误显示为可打印的字符串。
-spec getopts(SslSocket, OptionNames) -> {ok, [gen_tcp:option()]} | {error, reason()} when SslSocket :: sslsocket(), OptionNames :: [gen_tcp:option_name()].
获取指定套接字选项的值。
-spec getstat(SslSocket) -> {ok, OptionValues} | {error, inet:posix()} when SslSocket :: sslsocket(), OptionValues :: [{inet:stat_option(), integer()}].
获取底层套接字的统计信息。
-spec getstat(SslSocket, Options) -> {ok, OptionValues} | {error, inet:posix()} when SslSocket :: sslsocket(), Options :: [inet:stat_option()], OptionValues :: [{inet:stat_option(), integer()}].
获取底层套接的一个或多个统计值。
有关更多详细信息,请参见 inet:getstat/2
。
-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().
返回对等方的地址和端口号。
-spec prepend_cipher_suites(Preferred, Suites) -> ciphers() when Preferred :: ciphers() | cipher_filters(), Suites :: ciphers().
使 Preferred
套件成为最首选的套件。
如果 Preferred
套件存在于 Suites
列表中,则将其从 Suites
中删除后,将其放置在密码套件列表 Suites
的开头。Preferred
可以是密码套件列表,也可以是过滤器列表,在这种情况下,将对 Suites
使用过滤器以提取首选密码列表。
-spec signature_algs(Description, Version) -> signature_algs() when Description :: default | all | exclusive, Version :: protocol_version().
列出与 Description
对应的所有可用签名算法。
exclusive
选项将为该协议版本独占列出算法或算法方案,而 default
和 all
选项则列出组合列表,以支持从 (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
的本地地址和端口号。
-spec start() -> ok | {error, reason()}.
等效于 start(temporary)
。
-spec start(permanent | transient | temporary) -> ok | {error, reason()}.
启动 SSL 应用程序。
-spec stop() -> ok.
停止 SSL 应用程序。
-spec str_to_suite(CipherSuiteName) -> erl_cipher_suite() | {error, {not_recognized, CipherSuiteName}} when CipherSuiteName :: string().
将 RFC 或 OpenSSL 名称字符串转换为 erl_cipher_suite/0
如果不支持该密码套件或名称不是有效的密码套件名称,则返回错误。
-spec suite_to_openssl_str(CipherSuite) -> string() when CipherSuite :: erl_cipher_suite().
将 erl_cipher_suite()
值转换为 OpenSSL 名称字符串。
在 TLS-1.3 之前,这些名称与 RFC 名称不同。
-spec suite_to_str(CipherSuite) -> string() when CipherSuite :: erl_cipher_suite().
将 erl_cipher_suite()
值转换为 RFC 名称字符串。
-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,4
、listen/2
和handshake/2,3
上的 version 选项覆盖。 对于协商的 TLS 版本,请参阅connection_information/1
。supported_dtls
- 当前应用程序环境和加密库配置支持的 DTLS 版本。被connect/2,3,4
、listen/2
和handshake/2,3
上的 version 选项覆盖。 对于协商的 DTLS 版本,请参阅connection_information/1
。available
- 链接的加密库支持的所有 TLS 版本。available_dtls
- 链接的加密库支持的所有 DTLS 版本。implemented
- 如果与具有必要支持的加密库链接,则 SSL 应用程序支持的所有 TLS 版本。implemented_dtls
- 如果与具有必要支持的加密库链接,则 SSL 应用程序支持的所有 DTLS 版本。
已弃用的 API
-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) 生成额外的密钥材料。
它要么采用用户生成的 Secret
和 Seed
值,要么采用原子来指示其使用会话安全参数中的特定值。
注意
此函数已被 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])
。