Azure-Samples / Cognitive-Speech-TTS

Microsoft Text-to-Speech API sample code in several languages, part of Cognitive Services.
https://azure.microsoft.com/en-us/services/cognitive-services/text-to-speech/
Other
905 stars 512 forks source link

Azure Cognitive Speech TTS does not work on Windows 8, 8.1, Server 2012, Server 2012R2 since 2022-01 #221

Closed ivoryguard closed 2 years ago

ivoryguard commented 2 years ago

Hello.

I found an issue of Azure Cognitive Speech TTS Service; Azure Cognitive Speech TTS API does not work on Windows 8,/8.1/Server 2012/Server2012R2 since 2022-01.

I made a program with Microsoft Cognitive Services Speech SDK and it worked well on Windows 8/8.1/Server2012/Server2012R2 as well as Windows 10/Server 2019.

I confirmed that there were logs that it has worked correctly until 2021-11-30 at least. However, it does not work today.

So, I made a simple sample with Microsoft.CognitiveServices.Speech.csharp nuget package.

My sample code is as the following;

public static async Task SynthesisToAudioFileAsync(string text, string outputFileName)
{
    var config = SpeechConfig.FromSubscription("xxxxx", "westus2");

    config.SpeechSynthesisLanguage = "ko-KR";
    config.SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat.Audio24Khz48KBitRateMonoMp3);
    config.SpeechSynthesisVoiceName = "ko-KR-SunHiNeural";

    using (var fileOutput = AudioConfig.FromWavFileOutput(outputFileName))
    {
        using (var synthesizer = new SpeechSynthesizer(config, fileOutput))
        {
            var result = await synthesizer.SpeakTextAsync(text);

            if (result.Reason == ResultReason.SynthesizingAudioCompleted)
            {
                Console.WriteLine($"Speech synthesized to [{outputFileName}]");
            }
            else if (result.Reason == ResultReason.Canceled)
            {
                var cancellation = SpeechSynthesisCancellationDetails.FromResult(result);
                Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");

                if (cancellation.Reason == CancellationReason.Error)
                {
                    Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
                    Console.WriteLine($"CANCELED: ErrorDetails=[{cancellation.ErrorDetails}]");
                    Console.WriteLine($"CANCELED: Did you update the subscription info?");
                }
            }
            else
            {
                Console.Write(result.Reason.ToString());
            }
        }
    }

}

It works well on Windows 10/Server2019 with no error. However, it does not work on Windows 8,/8.1/Server 2012/Server2012R2. Of course, I executed windows update fully.

The error message is as the following;

CANCELED: Reason=Error
CANCELED: ErrorCode=ConnectionFailure
CANCELED: ErrorDetails=[Connection failed (no connection to the remote host). In
ternal error: 11. Error details: Code: 0. USP state: 2. Received audio size: 0 b
ytes.]
CANCELED: Did you update the subscription info?

I suspect that it may be TLS 1.2 issue and tried as the followings;

  1. I changed Microsoft.CognitiveServices.Speech.csharp nuget package to several versions - 1.14, 1.13 and 1.19(latest version) but it did not work.

  2. I tried to enable TLS 1.2 on Windows 8.1/Server2012 according to many google search results; https://github.com/MicrosoftDocs/memdocs/blob/main/memdocs/configmgr/core/plan-design/security/includes/update-net-framework-to-support-tls-1-2.md https://hide.me/en/knowledgebase/how-to-enable-tls-1-1-tls-1-2-in-windows-7-and-8/ https://docs.microsoft.com/en-us/mem/configmgr/core/plan-design/security/enable-tls-1-2-client

and other many postings.

But, it did not work.

  1. I downloaded Cognitive-Speech-TTS sample (Cognitive-Speech-TTS-master.zip) and run C# sample in Old folder. It does not use Azure SDK and implements https rest API in low level. So I can review and change codes.

It also worked on Windows 10 but did not work on Windows 81./Server2012 as the following error message;

Starting TTSSample request code execution.

Unhandled Exception: System.AggregateException: One or more errors occurred. ---> 
System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> 
System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
  at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context) 
 at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)

I confirmed that token API (https://westus2.api.cognitive.microsoft.com/sts/v1.0/issueToken) was called well but speak API (https://westus2.tts.speech.microsoft.com/cognitiveservices/v1) was not called with error message.

According to error message, it seems to TLS 1.2 issue.

So, I added to the following line;

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;

The error message became changed as the following on Windows 10 as well as Windows 8.1/Server2012

Starting Authtentication

Unhandled Exception: System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> 
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host ---> 
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
  at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)

It was expected behavior because I forced TLS 1.1. However, the error occurred in authentication step, contrary to above result - above test passed authentication.

So, TLS 1.2 may be enabled on my Windows 81./server2012 because token Uri may require TLS 1.2 according to above testing result.

I tired with speech recognition C# sample in cognitive-services-speech-sdk-master. It worked well Windows 81./Server2012 as well as Windows 10.

MS doc said that Azure Cognitive Service requires TLS 1.2.
If TLS 1.2 is not available on my Windows 8.1/Server2012, all Azure Cognitive Service API must fail. However, only TTS API fails. Beside, it has worked until 2021-11 at least.

I've tried almost everything I could, but failed.

Finally I suspect that there may be some changes in Azure Cognitive TTS system at the end of 2021 and it may make the issue related to TLS connection from Windows 8/8.1/Server2012/Server2012R2.

In fact, the issue was reported on my customer's machines and upgrading Windows OS to Windows10/Server2019 is not an option because of many reasons. So, I have to find a workaround on Windows 8/8.1/Server2012/Server2012R2.

Best regards.

ivoryguard commented 2 years ago

I captured network packets of Cognitive-Speech-TTS C# sample using WireShark and confirmed that TLS 1.2 was used.

First handshaking to retrieve token(westus2.api.cognitive.microsoft.com - 20.51.8.244) succeeded but second handshaking to Azure Cognitive TTS Service(westus2.tts.speech.microsoft.com - 20.51.12.193) failed with the following message;

TLSv1.2 Record Layer: Handshake Protocol: Client Hello
TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Handshake Failure). 

I tested on Windows 10 and all TLS 1.2 handshaking succeeded with same test console program.

I added the following code to ignore certificate validation but it did not work;

ServicePointManager.ServerCertificateValidationCallback += (object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors) =>
            {
                return true;
            };
ivoryguard commented 2 years ago

I found actual reason. It was TLS cipher suite issue of Azure TTS Service API Server.

I executed sslscan to westus2.tts.speech.microsoft.com and the result was as the following;

westus2.tts.speech.microsoft.com 
Preferred TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve 25519 DHE 253 
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384   Curve 25519 DHE 253 
Accepted  TLSv1.2  256 bits  ECDHE-RSA-CHACHA20-POLY1305   Curve 25519 DHE 253 

I compared packet capturing result of WireShark between Windows 8.1 and Windows 10.

The result of Windows 10 has ECDHE-RSA-AES128-GCM-SHA256 and ECDHE-RSA-AES256-GCM-SHA384 but the result of Windows 8.1 does not.

So, Azure TTS API cannot work on Windows8/8.1/Server2012/Server2012R2 and it must be fixed by MS.

yulin-li commented 2 years ago

close as fixed

jgriede commented 9 months ago

The same issue re-appeared (after 2 years) as of 2nd januari 2024.

Only these 3 TLS 1.2 ciphers seem to be active now for api.cognitive.microsofttranslator.com.

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256

While api.microsofttranslator.com and api.cognitive.microsoft.com still have much more TLS 1.2 ciphers active...

My company has a 2012 R2 ESU support contract with Microsoft so some other TLS 1.2 ciphers should still be supported.

@Microsoft, please fix this again asap in Azure.