sgcWebSockets 可以完全不加载任何 OpenSSL 库运行。有两个相互独立的设置能做到这一点,二者都建立在纯 Pascal 的 sgcCrypto 各单元之上,该单元从 Standard 版起提供。
iohNativeTLS 是一个 IOHandler 值。它替代 OpenSSL 承担组件的连接:TLS、QUIC 和 DTLS。参阅 原生 TLS。
sgcCryptoBackend 是一个运行时开关。它为应用加密(除连接以外的一切工作)选择后端:哈希、签名、密钥协商和证书处理。
既不需要 OpenSSL 承担连接、也不需要它承担其他加密工作的应用程序,会同时使用这两者。
sgcBase_Helpers 单元声明了类型为 TsgcCryptoBackend 的全局变量 sgcCryptoBackend:
cbOpenSSL(默认):应用加密运行在 OpenSSL 上,与之前版本相同。
cbNative:应用加密运行在 sgcCrypto 上,永远不会为此加载 OpenSSL。
cbAuto:能加载 OpenSSL 时使用 OpenSSL,不能加载时使用 sgcCrypto。该检测只运行一次,结果会被缓存。
该开关是全局的,不针对单个组件。请在创建任何组件之前、启动时设置一次。sgcUseNativeCrypto 在使用原生后端时返回 True。原生后端需要编译进 sgcCrypto 单元(SGC_CRYPTO)。如果没有编译进去,cbNative 会引发异常 "Native crypto not available, sgcCrypto units are not compiled in"。调用 sgcCheckNativeCrypto 可以在启动时就得到该错误,而不必等到首次使用时才发现。
uses
sgcBase_Helpers;
begin
sgcCryptoBackend := cbNative;
sgcCheckNativeCrypto;
Application.Initialize;
...
以下这些部分遵循该开关:
| 区域 | 原生运行的内容 |
| 哈希与 HMAC 辅助函数 | sgcBase_Helpers 的哈希和 HMAC 函数,以及 sgcEncryptString / sgcDecryptString。 |
| JWT、JWS 签名 | HMAC、RSA、RSA-PSS、ECDSA 和 EdDSA 的签名与验证(sgcSSL_RSA、sgcSSL_PS、sgcSSL_ES、sgcSSL_ED)。sgcES_GetCurveFromPublicKey 只能处理 OpenSSL 密钥,在原生后端上会引发异常。 |
| 证书 | sgcSSL 辅助函数:PEM 与 DER 转换、证书加载、CRL URI 以及证书链验证。 |
| OAuth2 与 DPoP | OAuth2 的 JWK 辅助函数,以及 OAuth2 服务器对 DPoP 证明的校验(ES256、ES384、ES512、RS256、RS384、RS512)。参阅 DPoP。 |
| Amazon | AWS Signature V4、CloudFront 签名 URL,以及 Amazon IoT MQTT 客户端的 Signature V4 身份验证,此时其 SignatureV4.OpenSSL_Options 会被忽略。 |
| Web Push | VAPID ES256 令牌、ECDH 密钥协商、HKDF 以及 AES-128-GCM 负载加密。只有到推送服务的 https 连接会通过其 IOHandler 加载 TLS 库。 |
| E2EE | 密钥协商、AES-GCM 以及随机数生成器。两种后端在网络上传输的公钥都是 PEM 格式,原始密钥格式仍然可以接受,因此不同后端的对端可以互通。 |
| WebAuthn、SAML、OIDC | WebAuthn 的证书、COSE 密钥和认证检查,以及 SAML 和 OIDC 使用的 XMLDSig 签名校验。 |
| NTLM | NTLM 身份验证的 MD4 和 DES 代码。它在所有构建中都是原生实现,不再需要任何编译器定义。 |
| AEAD、KEM、HKDF | sgcSSL_AEAD(AES-128-GCM、AES-256-GCM、ChaCha20-Poly1305)、sgcSSL_KEM(ML-KEM-768 和 ECDH P-256)以及 sgcSSL_HKDF(现在还支持 sgcHKDF_MD_SHA384)。ML-KEM-768 不需要 OpenSSL 3.5,且密钥编码与 OpenSSL 3.5 相同。在 FIPS 构建中,ChaCha20-Poly1305 不可用,会引发异常。 |
| QUIC、DTLS、SRTP | QUIC 报文保护、DTLS 证书以及 SRTP。使用 iohNativeTLS 时,无论该开关如何设置,它们每条连接都已经是原生实现。 |
sgcCryptoBackend 不会改变某个组件的 TLS 连接。保持 IOHandler = iohOpenSSL 的组件在连接时仍会加载 OpenSSL。
该定义默认关闭,现在已经不再是不使用 OpenSSL 运行所必需的了。不启用它时,OpenSSL 代码和原生代码都会被编译进去,由 sgcCryptoBackend 在运行时决定使用哪一个。启用它后,无论 sgcCryptoBackend 如何设置都会强制使用原生后端,并且应用加密单元中的 OpenSSL 代码会被移除,因此可执行文件更小。要启用它,请打开 sgcVer.inc,删除下面这一行前面的点:
{.$DEFINE SGC_NATIVE_CRYPTO}
或者把 SGC_NATIVE_CRYPTO 加入您项目的条件定义中。SGC_NATIVE_CRYPTO 同时会打开它所依赖的 sgcCrypto 单元所需的 SGC_CRYPTO。DISABLE_SGC_NATIVE_CRYPTO 可再次将其关闭。
需要哪些设置,取决于应用程序使用了什么:
| 区域 | 实现零 OpenSSL 的设置 |
| 基于 TCP 的 TLS:WebSocket、HTTP/1、HTTP/2、TCP、MQTT 及其他协议 | TLSOptions.IOHandler(客户端)或 SSLOptions.IOHandler(服务器)= iohNativeTLS。参阅 原生 TLS。 |
| QUIC 和 HTTP/3 | IOHandler = iohNativeTLS。握手、报文保护、密钥更新以及 Retry 标签均为原生实现。参阅 QUIC 和 HTTP/3。 |
| DTLS 和 WebRTC | DTLSOptions.IOHandler = iohNativeTLS。握手、DTLS 证书以及 SRTP 密钥均为原生实现。参阅 DTLSOptions 和 WebRTC DTLS。 |
| 应用加密:JWT、OAuth2、Web Push、Amazon Signature V4、E2EE、WebAuthn、SAML 以及第一张表中的其他区域 | 启动时设置 sgcCryptoBackend := cbNative,或者使用 SGC_NATIVE_CRYPTO 编译器定义。 |
iohNativeTLS 所在的几行都不需要任何编译器定义或 sgcCryptoBackend 设置。在不包含 sgcCrypto 单元的构建中选择 iohNativeTLS 会引发异常,绝不会静默回退到 OpenSSL。
使用 iohNativeTLS 时,TLS 1.3 和 TLS 1.2 握手以及记录层运行在原生引擎上。它适用于 WebSocket、HTTP/1、HTTP/2 和 TCP 客户端及服务器,以及建立在它们之上的一切:MQTT、AMQP、STOMP 及其他协议,各 API 组件,IoT 客户端(Certificate.IOHandler),代理服务器的上游连接(Proxy.TLSOptions),以及 LDAP 客户端。证书可以是 PEM、DER 或 .pfx / .p12 文件。