预共享密钥
【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,因为默认的将在没有证书的情况下失败。
【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 的函数(该 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:】
hint<string> 可选消息,由服务器发送,用于帮助客户端在协商过程中决定使用哪个身份。如果使用 TLS 1.3,则始终为null。- 返回:<Object>,形式为
{ psk: <Buffer|TypedArray|DataView>, identity: <string> }或null。
然后在服务器上:
【Then on the server:】
socket<tls.TLSSocket> 服务器套接字实例,相当于this。identity<string> 身份参数由客户端发送。- 返回:<Buffer> | <TypedArray> | <DataView> PSK(或
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.】