Rebex WebSocket
WebSocket library for modern and legacy platforms
Download 30-day free trial Buy from $349More .NET libraries
-
Rebex Total Pack
All Rebex .NET libraries together
Back to feature list...
TLS/SSL core
On this page:
TLS/SSL is a cryptographic communication protocol providing a way of securing protocols such as FTP, HTTP, SMTP, IMAP, POP3, Telnet or Syslog.
TLS and SSL are different versions of the same protocol. TLS 1.0 is a name for what was supposed to be SSL 3.1. When we use the terms "SSL" or "TLS", we generally mean "TLS or SSL".
Validating and examining server certificate
When connecting securely, you should ensure you are really connected to the desired server. TLS/SSL provides it with a security certificate of the server. On the client side you should just verify that the server certificate of the current connection really comes from the server you want to connect to. There are following ways, how to do it using the Rebex WebSocket:
- By default, the server certificate is validated against Windows certificate infrastructure.
- If you cannot rely on the built-in certificate verifier, you can write your own certificate validation.
-
The certificate validation can be simply skipped by setting the
SslAcceptAllCertificates
property:// create an instance of WebSocketClient // ... // skip certificate validation (don't do this in production environment!) client.Settings.SslAcceptAllCertificates = true;
' create an instance of WebSocketClient ' ... ' skip certificate validation (don't do this in production environment!) client.Settings.SslAcceptAllCertificates = True
Built-in certificate verifier
When calling the Connect
method and no custom validation is configured,
the server certificate is validated using Windows CryptoAPI.
See what to do when a server certificate is not trusted.
Legacy Windows CE platforms don't natively support certificates signed using algorithms based on SHA-2 hashes. As a workaround for this major OS limitation, we introduced a built-in certificate validator in the 2016 R3 release.
Custom certificate validation
If you cannot relay on the certificate can be trusted by the Windows certificate infrastructure, you can implement your own validation:
Register an event handler before calling the Connect
method
// create an instance of WebSocketClient // ... // register custom validation event handler client.ValidatingCertificate += client_ValidatingCertificate;
' create an instance of WebSocketClient ' ... ' register custom validation event handler AddHandler client.ValidatingCertificate, AddressOf client_ValidatingCertificate
Implement the custom validation within the event handler
public void client_ValidatingCertificate(object sender, SslCertificateValidationEventArgs e) { // first try to use the default validation (against the Windows certificate store) ValidationResult res = e.CertificateChain.Validate(e.ServerName, 0); if (res.Valid) { e.Accept(); return; } // get server certificate of the current connection Certificate cert = e.CertificateChain[0]; // check the certificate is already known if (trustedThumbprints.Contains(cert.Thumbprint)) { e.Accept(); return; } // the certificate is not know yet - show it to user Console.WriteLine("Do you trust to the following certificate?"); Console.WriteLine(" Common name: {0}", cert.GetCommonName()); Console.WriteLine(" Thumbprint: {0}", cert.Thumbprint); Console.WriteLine(" Expires on: {0:d}", cert.GetExpirationDate()); // ask user for the answer // ... // accept or reject the certificate if (userAnswer) { e.Accept(); // OPTIONALY store the current certificate as trusted trustedThumbprints.Add(cert.Thumbprint); } else { e.Reject(); } }
Public Sub client_ValidatingCertificate(sender As Object, e As SslCertificateValidationEventArgs) ' first try to use the default validation (against the Windows certificate store) Dim res As ValidationResult = e.CertificateChain.Validate(e.ServerName, 0) If res.Valid Then e.Accept() Return End If ' get server certificate of the current connection Dim cert As Certificate = e.CertificateChain(0) ' check the certificate is already known If trustedThumbprints.Contains(cert.Thumbprint) Then e.Accept() Return End If ' the certificate is not know yet - show it to user Console.WriteLine("Do you trust to the following certificate?") Console.WriteLine(" Common name: {0}", cert.GetCommonName()) Console.WriteLine(" Thumbprint: {0}", cert.Thumbprint) Console.WriteLine(" Expires on: {0:d}", cert.GetExpirationDate()) ' ask user for the answer ' ... ' accept or reject the certificate If userAnswer Then e.Accept() ' OPTIONALY store the current certificate as trusted trustedThumbprints.Add(cert.Thumbprint) Else e.Reject() End If End Sub
Client certificate authentication
Client certificates are an optional way to authenticate the client to the server. This is only possible when connecting/authenticating to a TLS/SSL-capable HTTP server.
A certificate with an associated private key is needed for client authentication. Assign the Settings.SslClientCertificateRequestHandler
property
to an implementation of certificate request handler that is called when the HTTP server asks for client certificate.
a) Use the built-in StoreSearch
handler, that searches the user's certificate store for a first suitable certificate:
// set a certificate request handler client.Settings.SslClientCertificateRequestHandler = CertificateRequestHandler.StoreSearch;
' set a certificate request handler client.Settings.SslClientCertificateRequestHandler = CertificateRequestHandler.StoreSearch
b) Use the built-in PFX-based certificate request handler:
// load a certificate chain from a .P12 or .PFX file CertificateChain certificate = CertificateChain.LoadPfx("mycert.p12", "password"); // set a certificate request handler client.Settings.SslClientCertificateRequestHandler = CertificateRequestHandler.CreateRequestHandler(certificate);
' load a certificate chain from a .P12 or .PFX file Dim certificate As CertificateChain = CertificateChain.LoadPfx("mycert.p12", "password") ' set a certificate request handler client.Settings.SslClientCertificateRequestHandler = CertificateRequestHandler.CreateRequestHandler(certificate)
c) Write a custom handler, for example to load the certificate from a .pfx/.p12 file:
private class MyCertRequestHandler : ICertificateRequestHandler { // This method is called during TLS/SSL negotiation // when the server requests client certificate authentication public CertificateChain Request(TlsSocket socket, DistinguishedName[] issuers) { // provide a certificate loaded from a .pfx/.p12 file return CertificateChain.LoadPfx(clientCertPath, clientCertPassword); } }
Private Class MyCertRequestHandler Implements ICertificateRequestHandler ' This method is called during TLS/SSL negotiation ' when the server requests client certificate authentication Public Function Request(socket As TlsSocket, issuers As DistinguishedName()) _ As CertificateChain _ Implements ICertificateRequestHandler.Request ' provide a certificate loaded from a .pfx/.p12 file Return CertificateChain.LoadPfx(clientCertPath, clientCertPassword) End Function End Class
Don't forget to register the handler:
// set a certificate request handler client.Settings.SslClientCertificateRequestHandler = new MyCertRequestHandler();
' set a certificate request handler client.Settings.SslClientCertificateRequestHandler = New MyCertRequestHandler()
Overriding SSL server name
Server certificate's common name should specify the server hostname - this ensures that the server presents a certificate that actually belongs to it. If the names are mismatched, you can still work around it.
Security settings and algorithms
When connecting with Rebex WebSocket via TLS/SSL, you can easily configure desired TLS versions, cipher suites, elliptic curves and other parameters.
TLS/SSL protocol versions
Use Settings.SslAllowedVersions
property (on client object) to enable or disable specific versions of the TLS/SSL protocol.
Supported versions:
- TLS 1.3 (not available on .NET Compact Framework)
- TLS 1.2
- TLS 1.1
- TLS 1.0
- SSL 3.0
Note: TLS 1.3 is still a very new protocol and some legacy servers have issues communicating with clients that support TLS 1.3 in addition to earlier versions. Therefore, to prevent interoperability issues, TLS 1.3 support is not enabled in Rebex WebSocket by default. To enable it:
- C#:
client.Settings.SslAllowedVersions |= TlsVersion.TLS13;
- VB.NET:
client.Settings.SslAllowedVersions = client.Settings.SslAllowedVersions Or TlsVersion.TLS13
Note: SSL 3.0 is no longer considered secure and it's disabled by default. To enable it:
- C#:
client.Settings.SslAllowedVersions |= TlsVersion.SSL30;
- VB.NET:
client.Settings.SslAllowedVersions = client.Settings.SslAllowedVersions Or TlsVersion.SSL30
TLS 1.3 cipher suites
The following TLS 1.3 ciphers are supported:
- TLS_AES_128_GCM_SHA256 (AES/GCM with 128-bit key)
- TLS_AES_256_GCM_SHA384 (AES/GCM with 256-bit key)
- TLS_CHACHA20_POLY1305_SHA256 (ChaCha20-Poly1305 AEAD cipher)
Use Settings.SetSymmetricCipherSuites(...)
method
(on the client object)
to specify a list of allowed TLS 1.3 symmetric cipher suites, and
Settings.GetSymmetricCipherSuites()
method to retrieve the current setting.
TLS 1.3 key exchange algorithms
The following TLS 1.3 key exchange algorithms are supported:
- secp256r1 (ECDH with NIST P-256 curve)
- secp384r1 (ECDH with NIST P-384 curve)
- secp521r1 (ECDH with NIST P-521 curve)
- X25519 (ECDH with Curve25519; needs a plugin on Windows 8.1 / Windows Server 2012 or earlier and on non-Windows platforms)
TLS 1.3 signature algorithms
The following TLS 1.3 signature algorithms are supported:
- ecdsa_secp256r1_sha256 (ECDSA with NIST P-256 curve and SHA-256)
- ecdsa_secp384r1_sha384 (ECDSA with NIST P-384 curve and SHA-384)
- ecdsa_secp521r1_sha512 (ECDSA with NIST P-521 curve and SHA-512)
- rsa_pss_rsae_sha256 (RSA with RSASSA-PSS scheme and SHA-256)
- rsa_pss_rsae_sha384 (RSA with RSASSA-PSS scheme and SHA-384)
- rsa_pss_rsae_sha512 (RSA with RSASSA-PSS scheme and SHA-512)
- ed25519 (EdDSA with edwards25519 curve and SHA-512)
In TLS 1.3, certificates signed by the following signature algorithms are supported:
- ECDSA with SHA-256, SHA-384 or SHA-512 (corresponds to TLS 1.3
ecdsa_secp256r1_sha256
,ecdsa_secp384r1_sha384
andecdsa_secp521r1_sha512
algorithms) - ECDSA with SHA-1 (legacy certificates; corresponds to TLS 1.3
ecdsa_sha1
algorithm) - RSASSA-PSS with SHA-256, SHA-384 or SHA-512 (corresponds to TLS 1.3
rsa_pss_rsae_sha256
,rsa_pss_rsae_sha384
andrsa_pss_rsae_sha512
algorithms) - RSASSA-PKCS1-v1_5 with SHA-256, SHA-384 or SHA-512 (corresponds to TLS 1.3
rsa_pkcs1_sha256
,rsa_pkcs1_sha384
andrsa_pkcs1_sha512
algorithms) - RSASSA-PKCS1-v1_5 with SHA-1 (legacy certificates; corresponds to TLS 1.3
rsa_pkcs1_sha1
algorithm) - EdDSA with edwards25519 curve and SHA-512 (corresponds to TLS 1.3
ed25519
; needs a custom certificate verifier)
TLS 1.2/1.1/1.0 cipher suites
The Settings.SslAllowedSuites
property
(on the client object)
makes it possible to specify a combination of following algorithms:
Cipher ID | Certificate Key Algorithm | Key Exchange Algorithm | Encryption Algorithm | MAC Alg. |
---|---|---|---|---|
RSA_WITH_AES_128_GCM_SHA256 | RSA | RSA | AES/GCM | AEAD |
RSA_WITH_AES_256_GCM_SHA384 | AES/GCM | AEAD | ||
RSA_WITH_AES_128_CBC_SHA256 | AES/CBC | SHA-256 | ||
RSA_WITH_AES_256_CBC_SHA256 | AES/CBC | SHA-256 | ||
RSA_EXPORT_WITH_RC4_40_MD5 | RC4 | MD5 | ||
RSA_WITH_RC4_128_MD5 | RC4 | MD5 | ||
RSA_WITH_RC4_128_SHA | RC4 | SHA-1 | ||
RSA_EXPORT_WITH_RC2_CBC_40_MD5 | RC2/CBC | MD5 | ||
RSA_EXPORT_WITH_DES40_CBC_SHA | DES/CBC | SHA-1 | ||
RSA_WITH_DES_CBC_SHA | DES/CBC | SHA-1 | ||
RSA_WITH_3DES_EDE_CBC_SHA | 3DES/CBC | SHA-1 | ||
RSA_EXPORT1024_WITH_DES_CBC_SHA | DES/CBC | SHA-1 | ||
RSA_EXPORT1024_WITH_RC4_56_SHA | RC4 | SHA-1 | ||
RSA_WITH_AES_128_CBC_SHA | AES/CBC | SHA-1 | ||
RSA_WITH_AES_256_CBC_SHA | AES/CBC | SHA-1 | ||
ECDHE_RSA_WITH_AES_128_GCM_SHA256 | RSA | Elliptic Curve Diffie-Hellman | AES/GCM | AEAD |
ECDHE_RSA_WITH_AES_256_GCM_SHA384 | AES/GCM | AEAD | ||
ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 | ChaCha20-Poly1305 | AEAD | ||
ECDHE_RSA_WITH_AES_128_CBC_SHA256 | AES/CBC | SHA-256 | ||
ECDHE_RSA_WITH_AES_256_CBC_SHA384 | AES/CBC | SHA-384 | ||
ECDHE_RSA_WITH_AES_128_CBC_SHA | AES/CBC | SHA-1 | ||
ECDHE_RSA_WITH_AES_256_CBC_SHA | AES/CBC | SHA-1 | ||
ECDHE_RSA_WITH_3DES_EDE_CBC_SHA | 3DES/CBC | SHA-1 | ||
ECDHE_RSA_WITH_RC4_128_SHA | RC4 | SHA-1 | ||
ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 | Elliptic Curve DSA | Elliptic Curve Diffie-Hellman | AES/GCM | AEAD |
ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 | AES/GCM | AEAD | ||
ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 | ChaCha20-Poly1305 | AEAD | ||
ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | AES/CBC | SHA-256 | ||
ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 | AES/CBC | SHA-384 | ||
ECDHE_ECDSA_WITH_AES_128_CBC_SHA | AES/CBC | SHA-1 | ||
ECDHE_ECDSA_WITH_AES_256_CBC_SHA | AES/CBC | SHA-1 | ||
ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA | 3DES/CBC | SHA-1 | ||
ECDHE_ECDSA_WITH_RC4_128_SHA | RC4 | SHA-1 | ||
DHE_RSA_WITH_AES_128_GCM_SHA256 | RSA | Diffie-Hellman | AES/GCM | AEAD |
DHE_RSA_WITH_AES_256_GCM_SHA384 | AES/GCM | AEAD | ||
DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 | ChaCha20-Poly1305 | AEAD | ||
DHE_RSA_WITH_AES_128_CBC_SHA256 | AES/CBC | SHA-256 | ||
DHE_RSA_WITH_AES_256_CBC_SHA256 | AES/CBC | SHA-256 | ||
DHE_RSA_EXPORT_WITH_DES40_CBC_SHA | DES/CBC | SHA-1 | ||
DHE_RSA_WITH_DES_CBC_SHA | DES/CBC | SHA-1 | ||
DHE_RSA_WITH_3DES_EDE_CBC_SHA | 3DES/CBC | SHA-1 | ||
DHE_RSA_WITH_AES_128_CBC_SHA | AES/CBC | SHA-1 | ||
DHE_RSA_WITH_AES_256_CBC_SHA | AES/CBC | SHA-1 | ||
DHE_DSS_WITH_AES_128_GCM_SHA256 | DSS | Diffie-Hellman | AES/GCM | AEAD |
DHE_DSS_WITH_AES_256_GCM_SHA384 | AES/GCM | AEAD | ||
DHE_DSS_WITH_AES_128_CBC_SHA256 | AES/CBC | SHA-256 | ||
DHE_DSS_WITH_AES_256_CBC_SHA256 | AES/CBC | SHA-256 | ||
DHE_DSS_EXPORT_WITH_DES40_CBC_SHA | DES/CBC | SHA-1 | ||
DHE_DSS_WITH_DES_CBC_SHA | DES/CBC | SHA-1 | ||
DHE_DSS_WITH_3DES_EDE_CBC_SHA | 3DES/CBC | SHA-1 | ||
DHE_DSS_WITH_AES_128_CBC_SHA | AES/CBC | SHA-1 | ||
DHE_DSS_WITH_AES_256_CBC_SHA | AES/CBC | SHA-1 | ||
DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA | DES/CBC | SHA-1 | ||
DHE_DSS_EXPORT1024_WITH_RC4_56_SHA | RC4 | SHA-1 | ||
DHE_DSS_WITH_RC4_128_SHA | RC4 | SHA-1 | ||
DH_anon_WITH_AES_256_CBC_SHA256 | no certificate | Diffie-Hellman | AES/CBC | SHA-256 |
DH_anon_WITH_AES_128_CBC_SHA256 | AES/CBC | SHA-256 | ||
DH_anon_WITH_AES_256_CBC_SHA | AES/CBC | SHA-1 | ||
DH_anon_WITH_AES_128_CBC_SHA | AES/CBC | SHA-1 | ||
DH_anon_WITH_RC4_128_MD5 | RC4 | MD5 | ||
DH_anon_WITH_3DES_EDE_CBC_SHA | 3DES/CBC | SHA-1 | ||
DH_anon_WITH_DES_CBC_SHA | DES/CBC | SHA-1 |
Settings.SslAllowVulnerableSuites
to true
.
However, this is strongly discouraged.
TlsCipherSuite.Fast
enum value.
TLS/SSL extensions
Rebex WebSocket supports Server Name Identification (SNI) extension and Renegotiation Indication extension.
TLS/SSL elliptic curves
The Settings.SslAllowedCurves
property (on client object) makes it possible to specify a set of enabled elliptic curves
used by ECDHE ciphers above. Supported elliptic curves:
Curve ID | Curve Name |
---|---|
NistP256* | NIST P-256 curve |
NistP384* | NIST P-384 curve |
NistP521* | NIST P-521 curve |
BrainpoolP256R1** | Brainpool P-256 R1 curve |
BrainpoolP384R1** | Brainpool P-384 R1 curve |
BrainpoolP512R1** | Brainpool P-512 R1 curve |
Curve25519*** | X25519 curve |
* These curves require a plugin on Xamarin, Mono, and legacy Windows platforms.
** These curves require a plugin on Xamarin, Mono, and Windows earlier than Windows 10 / Windows Server 2016.
*** These curves require a plugin on non-Windows platforms and on Windows earlier than Windows 10 / Windows Server 2016.
Certificate validation options
Use Settings.SslServerCertificateValidationOptions
property to specify various options for the build-in certificate verifier.
For example:
IgnoreCnNotMatch
(Ignore common name mismatch)SkipRevocationCheck
(Skip revocation check)IgnoreCnNotMatch
(Ignore invalid common name)IgnoreWrongUsage
(Ignore wrong usage)IgnoreTimeNotNested
(Ignore improperly nested validity periods)AllowUnknownCa
(Allow unknown certification authority)
Back to feature list...