预共享密钥
¥Pre-shared keys
TLS-PSK 支持可作为普通基于证书的身份验证的替代方法。它使用预共享密钥而不是证书来验证 TLS 连接,提供相互验证。TLS-PSK 和公钥基础设施并不相互排斥。客户端和服务器可以同时容纳两者,在正常的密码协商步骤中选择它们中的任何一个。
¥TLS-PSK support is available as an alternative to normal certificate-based authentication. It uses a pre-shared key instead of certificates to authenticate a TLS connection, providing mutual authentication. TLS-PSK and public key infrastructure are not mutually exclusive. Clients and servers can accommodate both, choosing either of them during the normal cipher negotiation step.
TLS-PSK 只是一个不错的选择,因为存在与每台连接机器安全共享密钥的方法,因此它不会取代大多数 TLS 使用的公钥基础设施(PKI)。OpenSSL 中的 TLS-PSK 实现近年来出现了许多安全漏洞,主要是因为它仅被少数应用使用。在切换到 PSK 密码之前,请考虑所有替代解决方案。在生成 PSK 时,使用 RFC 4086 中讨论的足够的熵至关重要。从密码或其他低熵来源导出共享秘密是不安全的。
¥TLS-PSK is only a good choice where means exist to securely share a key with every connecting machine, so it does not replace the public key infrastructure (PKI) for the majority of TLS uses. The TLS-PSK implementation in OpenSSL has seen many security flaws in recent years, mostly because it is used only by a minority of applications. Please consider all alternative solutions before switching to PSK ciphers. Upon generating PSK it is of critical importance to use sufficient entropy as discussed in RFC 4086. Deriving a shared secret from a password or other low-entropy sources is not secure.
默认情况下禁用 PSK 密码,因此使用 TLS-PSK 需要使用 ciphers
选项明确指定密码套件。可用密码列表可以通过 openssl ciphers -v 'PSK'
检索。所有 TLS 1.3 密码都符合 PSK 的条件,并且可以通过 openssl ciphers -v -s -tls1_3 -psk
检索。在客户端连接上,应该传递自定义 checkServerIdentity
,因为如果没有证书,默认 checkServerIdentity
将失败。
¥PSK ciphers are disabled by default, and using TLS-PSK thus requires explicitly
specifying a cipher suite with the ciphers
option. The list of available
ciphers can be retrieved via openssl ciphers -v 'PSK'
. All TLS 1.3
ciphers are eligible for PSK and can be retrieved via
openssl ciphers -v -s -tls1_3 -psk
.
On the client connection, a custom checkServerIdentity
should be passed
because the default one will fail in the absence of a certificate.
根据 RFC 4279,必须支持长度最大为 128 字节的 PSK 标识和长度最大为 64 字节的 PSK。从 OpenSSL 1.1.0 开始,最大身份大小为 128 字节,最大 PSK 长度为 256 字节。
¥According to the RFC 4279, PSK identities up to 128 bytes in length and PSKs up to 64 bytes in length must be supported. As of OpenSSL 1.1.0 maximum identity size is 128 bytes, and maximum PSK length is 256 bytes.
由于底层 OpenSSL API 的限制,当前的实现不支持异步 PSK 回调。
¥The current implementation doesn't support asynchronous PSK callbacks due to the limitations of the underlying OpenSSL API.
要使用 TLS-PSK,客户端和服务器必须指定 pskCallback
选项,该函数返回要使用的 PSK(必须与所选密码的摘要兼容)。
¥To use TLS-PSK, client and server must specify the pskCallback
option,
a function that returns the PSK to use (which must be compatible with
the selected cipher's digest).
它将首先在客户端上调用:
¥It will be called first on the client:
-
暗示:<string> 可选消息从服务器发送,以帮助客户端决定在协商期间使用哪个身份。如果使用 TLS 1.3,则始终为
null
。¥hint: <string> optional message sent from the server to help the client decide which identity to use during negotiation. Always
null
if TLS 1.3 is used. -
返回:<Object> 的形式为
{ psk: <Buffer|TypedArray|DataView>, identity: <string> }
或null
。¥Returns: <Object> in the form
{ psk: <Buffer|TypedArray|DataView>, identity: <string> }
ornull
.
然后在服务器上:
¥Then on the server:
-
插座:<tls.TLSSocket> 服务器套接字实例,相当于
this
。¥socket: <tls.TLSSocket> the server socket instance, equivalent to
this
. -
身份:<string> 客户端发送的身份参数。
¥identity: <string> identity parameter sent from the client.
-
返回:<Buffer> | <TypedArray> | <DataView> PSK(或
null
)。¥Returns: <Buffer> | <TypedArray> | <DataView> the PSK (or
null
).
null
的返回值会停止协商过程并向另一方发送 unknown_psk_identity
警报消息。如果服务器希望隐藏 PSK 身份未知的事实,回调必须提供一些随机数据作为 psk
,以使与 decrypt_error
的连接在协商完成之前失败。
¥A return value of null
stops the negotiation process and sends an
unknown_psk_identity
alert message to the other party.
If the server wishes to hide the fact that the PSK identity was not known,
the callback must provide some random data as psk
to make the connection
fail with decrypt_error
before negotiation is finished.