Eliminar las DLL de OpenSSL de una aplicación Delphi solía ser una decisión de compilación. Activabas una directiva del compilador, recompilabas y distribuías un segundo ejecutable a los clientes que no podían tener OpenSSL en sus máquinas. sgcWebSockets 2026.10 lo convierte en una decisión en tiempo de ejecución: una variable global, fijada una sola vez al arrancar, decide si la criptografía de la aplicación se ejecuta sobre OpenSSL o sobre la criptografía integrada en la librería, escrita en Object Pascal.
El lado de la conexión, TLS sin OpenSSL, se explica en Delphi TLS 1.3 sin DLLs de OpenSSL. Esta entrada trata de todo lo demás: las firmas, los hashes, el acuerdo de claves y el cifrado que tu aplicación hace fuera del handshake TLS.
Una línea al arrancar
La unidad sgcBase_Helpers declara la variable global sgcCryptoBackend, de tipo TsgcCryptoBackend:
uses
sgcBase_Helpers;
begin
sgcCryptoBackend := cbNative;
sgcCheckNativeCrypto;
Application.Initialize;
...
El interruptor es global, no por componente, así que fíjalo antes de crear ningún componente. sgcCheckNativeCrypto es opcional: si las unidades de criptografía nativa no están compiladas, lanza un mensaje claro al arrancar en lugar de fallar en la primera firma que intente hacer tu aplicación.
Tres valores
cbOpenSSLes el valor por defecto. La criptografía de la aplicación se ejecuta sobre OpenSSL, exactamente igual que en versiones anteriores, así que actualizar no cambia nada hasta que fijas la variable.cbNativeejecuta la criptografía de la aplicación sobre la implementación en Object Pascal. OpenSSL nunca se carga para ella.cbAutousa OpenSSL cuando sus librerías se pueden cargar, y el código nativo cuando no. La comprobación se ejecuta una sola vez y el resultado se guarda en caché.
cbAuto es el que conviene para productos que se distribuyen de las dos formas. Algunos clientes instalan las librerías de OpenSSL junto al ejecutable, a otros no se les permite, y la misma compilación funciona para ambos sin un ticket de soporte por una DLL que falta.
// same executable, with or without the OpenSSL libraries beside it
sgcCryptoBackend := cbAuto;
Lo que cubre el interruptor
El interruptor cubre la criptografía que los componentes hacen en tu nombre:
- los ayudantes de hashing y HMAC;
- la firma y verificación de JWT, HS, RS y ES;
- las pruebas de OAuth2 y DPoP;
- AWS Signature V4 y las URL firmadas de CloudFront;
- Web Push;
- el cifrado de extremo a extremo (E2EE), donde interlocutores con backends distintos interoperan, así que un cliente en
cbNativehabla con un servidor que sigue en OpenSSL; - WebAuthn y las passkeys;
- SAML y las firmas XML;
- NTLM;
- AEAD, ML-KEM y HKDF;
- la protección de paquetes QUIC, los certificados DTLS y WebRTC, y SRTP.
Ninguna de ellas necesita un cambio de código. Un JWT que ayer se firmaba con OpenSSL hoy se firma de forma nativa porque la variable lo dice.
Las conexiones son un ajuste aparte
sgcCryptoBackend no cambia cómo se conecta un componente. El TLS de una conexión se elige por componente, con IOHandler = iohNativeTLS, en los componentes TCP, HTTP y WebSocket y todo lo que se construye sobre ellos, como MQTT, en QUIC y HTTP/3, y en DTLSOptions para WebRTC:
sgcCryptoBackend := cbNative; // application crypto
oClient.TLSOptions.IOHandler := iohNativeTLS; // this connection
Un componente que mantiene el handler de OpenSSL sigue cargando OpenSSL al conectar. Con iohNativeTLS en QUIC, HTTP/3 y DTLS, no se usa OpenSSL en absoluto, diga lo que diga el interruptor. Una aplicación que no quiere OpenSSL en ningún sitio fija ambas cosas: el interruptor para su criptografía, y el handler en cada componente que abre una conexión segura.
La directiva ahora es opcional
Hasta ahora, ejecutar sin OpenSSL significaba la directiva de compilador SGC_NATIVE_CRYPTO. Ya no hace falta. Sin ella, tanto el código de OpenSSL como el nativo se compilan y la variable decide en tiempo de ejecución.
La directiva todavía tiene un uso. Fuerza el backend nativo diga lo que diga sgcCryptoBackend y elimina el código de OpenSSL de las unidades de criptografía de la aplicación, así que el ejecutable es más pequeño. Si sabes que una compilación nunca va a usar OpenSSL, sigue siendo la opción correcta. Si todavía no lo sabes, déjala desactivada y decide al arrancar.
Por qué importa
- Una sola compilación. Los clientes que deben distribuir sin OpenSSL, por licencias, por una auditoría de seguridad que pregunta por cada binario de terceros, o por máquinas bloqueadas donde nadie puede copiar una DLL, reciben el mismo ejecutable que todos los demás.
- Una alternativa.
cbAutomantiene una aplicación funcionando cuando faltan las librerías de OpenSSL, en lugar de fallar en la primera firma. - Móvil. En iOS y Android no hay OpenSSL que empaquetar para la criptografía de la aplicación.
- El mismo código en todas partes. El interruptor funciona igual en Windows, Linux, macOS, iOS y Android, con Delphi 7 a Delphi 13 y C++Builder.
Actualización
Nada cambia hasta que fijas la variable, porque cbOpenSSL es el valor por defecto. Para probar el backend nativo, añade las dos líneas anteriores a tu archivo de proyecto, ejecuta tus pruebas y compara. La lista completa de lo que depende del interruptor, y qué ajuste necesita cada área para cero OpenSSL en tiempo de ejecución, está en el tema de ayuda Ejecutar sin OpenSSL.
Sigue leyendo
- Delphi TLS 1.3 sin DLLs de OpenSSL, el lado de la conexión
¿Preguntas, comentarios o ayuda con la migración? Ponte en contacto. Recibirás respuesta de las mismas personas que escribieron el código.
