admin管理员组

文章数量:1123687

I've been connecting to Bloomberg's SOAP web services (DataLicense) for years without any SSL issues. After upgrading my project from .NET 8 to .NET 9, calls to the service fail with a TLS/SSL handshake error.

With .NET 8, the exact same code runs fine on Windows 11.

In Fiddler, I can see a TLS 1.2 handshake, so it doesn’t look like a TLS version problem.

Below is a minimal repro code snippet. In .NET 8 it works. In .NET 9 it fails at the submitGetHistoryRequest(...) call, complaining about SSL or failing to negotiate the connection.

using System;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.Text;
using DataLicense;

namespace BloombergConnectionTest
{
    public class DlClient
    {
        private static PerSecurityWSClient _client { get; set; }

        public static PerSecurityWSClient GetClient()
        {
            string p12Path = "xxxx";
            // Read the raw bytes
            byte[] rawData = File.ReadAllBytes(p12Path);

            // This works fine in .NET 8, fails in .NET 9 with an SSL error
            X509Certificate2 clientCert = new X509Certificate2(rawData, "zzzzz",
                X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);

            var binding = GetBinding();
            binding.OpenTimeout = TimeSpan.FromMinutes(10);
            binding.CloseTimeout = TimeSpan.FromMinutes(10);
            binding.SendTimeout = TimeSpan.FromMinutes(10);
            binding.ReceiveTimeout = TimeSpan.FromMinutes(10);

            var endpoint = new EndpointAddress(";);
            var client = new PerSecurityWSClient(binding, endpoint);
            client.ClientCredentials.ClientCertificate.Certificate = clientCert;
            _client = client;

            return _client;
        }

        public static BasicHttpBinding GetBinding()
        {
            var binding = new BasicHttpBinding
            {
                Name = "PerSecurityWSBinding",
                CloseTimeout = TimeSpan.FromMinutes(1),
                OpenTimeout = TimeSpan.FromMinutes(1),
                ReceiveTimeout = TimeSpan.FromMinutes(10),
                SendTimeout = TimeSpan.FromMinutes(1),
                BypassProxyOnLocal = false,
                MaxBufferPoolSize = 524288,
                MaxBufferSize = 65536000 * 10,
                MaxReceivedMessageSize = 65536000 * 10,
                TextEncoding = Encoding.UTF8,
                UseDefaultWebProxy = true,
                AllowCookies = false,
                TransferMode = TransferMode.Buffered
            };
            binding.ReaderQuotas.MaxDepth = 32;
            binding.ReaderQuotas.MaxArrayLength = 16384;
            binding.ReaderQuotas.MaxStringContentLength = 8192;
            binding.ReaderQuotas.MaxBytesPerRead = 4096;
            binding.ReaderQuotas.MaxNameTableCharCount = 16384;
            binding.Security.Mode = BasicHttpSecurityMode.Transport;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
            binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
            return binding;
        }
    }
}      

Then I call:

var ps = DlClient.GetClient();

if (ps.State != CommunicationState.Opened)
    ps.Open();

// Fails in .NET 9 with an SSL error
var sbmtGtHistResp = ps.submitGetHistoryRequest(sbmtGtHistReq);

Observations so far:

  • On .NET 8, everything works. Same code, same .p12 file, same machine (Windows 11).
  • On .NET 9, I see an SSL handshake error when submitGetHistoryRequest is called.
  • Fiddler shows it’s using TLS 1.2, so it’s not trying older protocols like SSL 3.

I've tried different key-storage flags (EphemeralKeySet, etc.), but still no luck.

Question: what changed in .NET 9 that might cause an SSL/TLS handshake failure for a WCF SOAP client with a client certificate, and what else can I try so that the handshake still succeeds as it did in .NET 8?

Note: the .NET 9 code works when running on Azure via the task scheduler and the option "run whether user is logged on or not" which I cannot explain why. Using Fiddler while it's running and that'll make it fail on the same error

Fiddler result:

A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below.

Version: 3.3 (TLS/1.2) Random: 39 0B E6 26 9E 0B E5 1D 7F C0 A7 A5 4C 90 68 3D 37 BC A9 BD 81 78 8C 60 86 48 3C 58 22 76 78 C8 "Time": 06/09/1990 09:39:21 SessionID: D4 DE 74 DC F3 E3 85 F1 00 65 53 80 69 06 83 A4 F2 99 FF 58 A6 16 16 06 2F A0 64 A3 E6 63 D4 3B Extensions: server_name dlws.bloomberg supported_versions Tls1.3, Tls1.2, Tls1.1, Tls1.0 signature_algs rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_sha1, dsa_sha1, rsa_pkcs1_sha512, ecdsa_secp521r1_sha512 SessionTicket empty supported_groups x25519 [0x1d], secp256r1 [0x17], secp384r1 [0x18] key_share 00 CE 00 1D 00 20 A8 62 6B C8 AE FB 5B 10 6B 8B 24 8B 10 A4 96 F3 DC 84 62 8C C5 A0 41 87 F7 4E 15 01 D2 F3 31 6D 00 17 00 41 04 39 AB 75 5A D1 53 4A 7E 07 43 19 76 C3 FC 21 06 DF 1B 54 19 50 32 50 33 2B 7B 0C D8 1B F0 5D 19 EF 5A 28 B5 99 D5 07 9F CD 9C 8D 6C 9C 64 61 BA F0 80 D2 29 CB 18 04 21 11 68 DB 86 EB 8D 24 EC 00 18 00 61 04 36 16 1A 95 0F 52 EE 6B D1 A1 DC 50 FF F9 96 B9 56 99 C4 22 AE 24 98 41 0E 3C 14 BF BB 55 14 6E 5D 8C 62 96 68 41 E5 60 33 D8 CD C5 74 27 DF 7E 8E 77 43 AE FB CD FC 8A A0 2B 2E FD 00 53 71 55 E0 76 7C C9 78 6D 38 4D 02 E5 2F B5 55 1A BF 89 AF 7C B8 73 D5 44 BC 51 6C 9E B0 60 B4 D5 8C 0B post_handshake_auth extended_master_secret empty renegotiation_info 00 psk_key_exchange_modes 01 01 Ciphers: [1302] TLS_AES_256_GCM_SHA384 [1301] TLS_AES_128_GCM_SHA256 [C030] TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 [C02F] TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [C028] TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 [C027] TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 [C014] TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA [C013] TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA [C02C] TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 [C02B] TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 [C024] TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 [C023] TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 [C00A] TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA [C009] TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA [009D] TLS_RSA_WITH_AES_256_GCM_SHA384 [009C] TLS_RSA_WITH_AES_128_GCM_SHA256 [003D] TLS_RSA_WITH_AES_256_CBC_SHA256 [003C] TLS_RSA_WITH_AES_128_CBC_SHA256 [0035] TLS_RSA_WITH_AES_256_CBC_SHA [002F] TLS_RSA_WITH_AES_128_CBC_SHA

Compression: [00] NO_COMPRESSION

=>

fiddlerwork.https> HTTPS handshake to dlws.bloomberg (for #2652) failed. System.Security.Authentication.AuthenticationException A call to SSPI failed, see inner exception. < The message received was unexpected or badly formatted

Win32 (SChannel) Native Error Code: 0x80090326

本文标签: