Kafka Producer in .Net - SSL Handshake Failed - c#

This is the first time I am trying to connect to Kafka server using Asp.Net console app and I ran into a bunch of issues. I solved most but can't shake this one off.
I am testing the producer part and keep getting "SSL Handshake Failed" error. I followed some suggestions here, including setting SslEndpointIdentificationAlgorithm to blank.
This is my producer config section:
_producerConfig = new ProducerConfig
{
BootstrapServers = bootstrapServer,
EnableDeliveryReports = true,
ClientId = Dns.GetHostAddresses(),
//SecurityProtocol = SecurityProtocol.SaslSsl,
SecurityProtocol = SecurityProtocol.Ssl,
SslCaLocation = #"D:\Something\Certificate\myCert.pem",
SslKeyPassword = "blahblah",
SslEndpointIdentificationAlgorithm=SslEndpointIdentificationAlgorithm.None
};
...
public async Task StartSendingMessages(string topicName)
{
using (var producer = new ProducerBuilder<long, string>(_producerConfig)
.SetKeySerializer(Serializers.Int64)
.SetValueSerializer(Serializers.Utf8)
.SetLogHandler((_, message) => Console.WriteLine($"Facility: {message.Facility}-{message.Level} Message: {message.Message}"))
.SetErrorHandler((_, e) => Console.WriteLine($"Error: {e.Reason}. Is Fatal: {e.IsFatal}"))
.Build())
try
{
Console.WriteLine("\nProducer loop started...\n\n");
for (var character = 'A'; character <= 'C'; character++)
{
var message = $"Character #{character} sent at {DateTime.Now:yyyy-MM-dd_HH:mm:ss}";
var deliveryReport = await producer.ProduceAsync(topicName,
new Message<long, string>
{
Key = DateTime.UtcNow.Ticks,
Value = message
});
When I run the application, I get:
Facility: FAIL-Error Message: [thrd:ssl://1.2.3.4:9093/bootstrap]: ssl://1.2.3.4:9093/bootstrap: SSL handshake failed: ssl\statem\statem_clnt.c:1890:tls_post_process_server_certificate error:0A000086:SSL routines::certificate verify failed: broker certificate could not be verified, verify that ssl.ca.location is correctly configured or root CA certificates are installed (add broker's CA certificate to the Windows Root certificate store) (after 46ms in state SSL_HANDSHAKE)
Error: ssl://1.2.3.4:9093/bootstrap: SSL handshake failed: ssl\statem\statem_clnt.c:1890:tls_post_process_server_certificate error:0A000086:SSL routines::certificate verify failed: broker certificate could not be verified, verify that ssl.ca.location is correctly configured or root CA certificates are installed (add broker's CA certificate to the Windows Root certificate store) (after 46ms in state SSL_HANDSHAKE). Is Fatal: False
What am I doing wrong, or missing?

Related

How to connect mqtt with websocket in c#?

I tried use MQTTnet to connect mqtt.
But seems not worked, it would show the error message:
Unable to connect the remote server, the request was aborted: Could not create SSL/TLS secure channel.
I also found error message on windows event:
A fatal alert was received from the remote endpoint. The TLS protocol defined fatal alert code is 40.
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Options;
public override void Run()
{
var option = new MqttClientOptionsBuilder()
.WithWebSocketServer("wss://mymqttserver:443")
.WithClientId(Guid.NewGuid().ToString())
.WithTls(new MqttClientOptionsBuilderTlsParameters()
{
AllowUntrustedCertificates = true,
UseTls = true,
SslProtocol = SslProtocols.Tls12,
CertificateValidationCallback = delegate { return true; },
})
.WithCleanSession()
.Build();
var mqtt = new MqttFactory().CreateMqttClient() as MqttClient;
mqtt.ConnectAsync(option).Wait();
string convertMsg = JsonConvert.SerializeObject("Mqtt Connect Successfully!!");
var appMsg = new MqttApplicationMessage();
appMsg.Payload = Encoding.UTF8.GetBytes(convertMsg);
appMsg.Topic = "myTopic";
appMsg.QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce;
appMsg.Retain = false;
mqttClient.PublishAsync(appMsg).Wait();
}
I also tried connect my mqtt server with third party application.
It can connect successfully, so my mqtt server should be okay.
But I don't know why I can't use c# to connect.
In the line
.WithWebSocketServer("wss://mymqttserver:443")
You must remove the "wss://" because that is already being specified using the method ".WithWebSocketServer". So, you would have
.WithWebSocketServer("mymqttserver:443")
Just use the server and the port.

how to send email using MailKit in Asp.Net Core

Am not sure whether the old method of sending Mail using Mailkit is quite working with this code below
try
{
var emailMessage = new MimeMessage();
emailMessage.From.Add(new MailboxAddress(_emailConfig.SenderName, _emailConfig.SenderAddress));
emailMessage.To.Add(new MailboxAddress(email));
emailMessage.Subject = subject;
var builder = new BodyBuilder
{
HtmlBody = message
};
emailMessage.Body = builder.ToMessageBody();
using var smtp = new SmtpClient
{
ServerCertificateValidationCallback = (s, c, h, e) => true
};
smtp.AuthenticationMechanisms.Remove("XOAUTH2");
await smtp.ConnectAsync(_emailConfig.SmtpServer, Convert.ToInt32(_emailConfig.Port), false).ConfigureAwait(false);
await smtp.AuthenticateAsync(_emailConfig.Username, _emailConfig.Password).ConfigureAwait(false);
await smtp.SendAsync(emailMessage).ConfigureAwait(false);
await smtp.DisconnectAsync(true).ConfigureAwait(false);
}
catch (Exception ex)
{
throw new InvalidOperationException(ex.Message);
}
but am having exceptions if i use the code above to send email
nvalidOperationException: 534: 5.7.14 <https://accounts.google.com/signin/continue?sarp=1&scc=1&plt=AKgnsbv
5.7.14 26mzQKtlwfyEdGzHHdpi3ewWG6skAWgOBbdNNYmwzr9Sg3fGu-KixLAfODpJsVafutidE
5.7.14 8xBOp_8rNCvk9Y6iEcOkDlcZ1d-483zQ1Krw04NvqxQdq3w4iTtC8E9bL8uGprgV>
5.7.14 Please log in via your web browser and then try again.
5.7.14 Learn more at
5.7.14 https://support.google.com/mail/answer/78754 o5sm2555896wmh.8 - gsmtp
so when i changed this line of code below to use SSLS, A new error came out
await smtp.ConnectAsync(_emailConfig.SmtpServer, Convert.ToInt32(_emailConfig.Port), true).ConfigureAwait(false);
Exception returned
InvalidOperationException: An error occurred while attempting to establish an SSL or TLS connection.
This usually means that the SSL certificate presented by the server is not trusted by the system for one or more of
the following reasons:
1. The server is using a self-signed certificate which cannot be verified.
2. The local system is missing a Root or Intermediate certificate needed to verify the server's certificate.
3. A Certificate Authority CRL server for one or more of the certificates in the chain is temporarily unavailable.
4. The certificate presented by the server is expired or invalid.
Another possibility is that you are trying to connect to a port which does not support SSL/TLS.
It is also possible that the set of SSL/TLS protocols supported by the client and server do not match.
See https://github.com/jstedfast/MailKit/blob/master/FAQ.md#SslHandshakeException for possible solutions.
have searched everywhere on how to do it,even turned on my less secured app. some recommended sendGrid, i created a free account with them also,but i dont have access to the account created. Does anyone knows how to fix the code above using Mailkit
Try it like this.
using (var smtpClient = new SmtpClient())
{
smtpClient.ServerCertificateValidationCallback = (s, c, h, e) => true;
await smtpClient.ConnectAsync("host", port, false);
if (smtpClient.Capabilities.HasFlag(SmtpCapabilities.Authentication))
{
smtpClient.AuthenticationMechanisms.Remove("XOAUTH2");
await smtpClient.AuthenticateAsync(username, password);
}
await smtpClient.SendAsync(mailMsg);
smtpClient.Disconnect(true);
}

Client Certificate Authentication failed in WebRequest\HttpClient C#

Our customer met a fail when they were authenticated via Client Certificate Authentication.
The use IISCrypto completed their Tls1.2 configuration. The SSL protocols and TLS1.1 are marked disabled.
And they use IISCrypto completed their Cipher Suite configuration.
I checked Cipher Suite\ .net Framework version \ OS version \ Renegotiation of TLS \ Server Certificate Setting \ API Gateway Settings \ Windows Services.
But I cannot get any result.
Then I try to write some troubleshooting program to test the comunication and handshake sequence.
I got nothing.
Curl.exe and openssl s_client were ok when send message with Client certificate, but it always failed in C#, my code is like:
X509Certificate2 cert = new X509Certificate2(#"C:\Communicate.pfx", "xxxxx");
HttpClient client = null;
System.Net.Http.WebRequestHandler _internalHandler = new System.Net.Http.WebRequestHandler();
_internalHandler.UseProxy = false;
_internalHandler.ClientCertificates.Add(cert);
_internalHandler.ServerCertificateValidationCallback = ((obj, x509, chain, policyError) =>
{
return true;
});
client = new HttpClient(_internalHandler);
client.BaseAddress = new Uri(string.Format("https://{0}:{1}/", args[0], int.Parse(args[1])));
================================Update======================
I tried to write a TCP requester to test. It succeed. It seems the client certificate selection handler is different between HttpClient\WebRequest and SslStream.
X509Certificate2 cert = new X509Certificate2(#"C:\Communicate.pfx", "xxxxxxxx");
X509Certificate2Collection col = new X509Certificate2Collection();
col.Add(cert);
TcpClient client = new TcpClient(args[0], int.Parse(args[1]));
Stream stream = client.GetStream();
SslStream ssl = new SslStream(stream, false, new RemoteCertificateValidationCallback((a, b, c, d) =>
{
return true;
}),
new LocalCertificateSelectionCallback((sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers)=>
{
return cert;
}));
ssl.AuthenticateAsClient("1.1.1.1", col, System.Security.Authentication.SslProtocols.Tls12, false);
string x = "GET /api/TimebasedProxy/ HTTP/1.1\r\n";
x += "Host:1.1.1.1\r\n";
x += "Content-Type: application/json\r\n";
x += "Connection: Close\r\n\r\n";
byte[] xs = Encoding.UTF8.GetBytes(x);
ssl.Write(xs, 0, xs.Length);
================Update=============
I got the reason:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\SendTrustedIssuerList is set to 1 at the server side.
(https://learn.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#sendtrustedissuerlist)
But customer is running their server under Windows Server 2012R2, who set SendTrustedIssuerList to 1?
==========================Update=============
IISCrypto did it.
What ever you did with IISCrypto, IISCrypto always sets SendTrustedIssuerList to 1.
It is a bug.
I got the reason:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\SendTrustedIssuerList is set to 1 at the server side.
(https://learn.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#sendtrustedissuerlist)
But customer is running their server under Windows Server 2012R2, who set SendTrustedIssuerList to 1?
IISCrypto did it.
What ever you did with IISCrypto, IISCrypto always sets SendTrustedIssuerList to 1.
It is a bug.

C# - TLS / SSL Websockets using fleck

Im trying to make a TLS/SSL websocket connection using Fleck lib.
https://github.com/statianzo/Fleck (0.9.8.25)
now i got the server startet .
but when a client connects i get the following message.
28-02-2014 19:16:15 [Info] Server started at wss://localhost:8081
28-02-2014 19:18:51 [Debug] Client connected from 127.0.0.1:62543
28-02-2014 19:18:51 [Debug] Authenticating Secure Connection
28-02-2014 19:18:52 [Debug] 0 bytes read. Closing.
anybody got an idea of what im doing wrong ?
Browser: Chrome, version : 33.0.1750.117
// sample code.
FleckLog.Level = LogLevel.Debug;
var allSockets = new List<IWebSocketConnection>();
var server = new WebSocketServer("wss://localhost:8081");
server.Certificate = new X509Certificate2(#"CRT.pfx", "Pwd");
server.Start(socket =>
{
socket.OnOpen = () =>
{
Console.WriteLine("Open!");
allSockets.Add(socket);
};
socket.OnClose = () =>
{
Console.WriteLine("Close!");
allSockets.Remove(socket);
};
socket.OnMessage = message =>
{
foreach (var user in allSockets.ToList())
{
if(user.ConnectionInfo.Id != socket.ConnectionInfo.Id){
user.Send(message);
}
}
};
});
var input = Console.ReadLine();
while (input != "exit")
{
foreach (var socket in allSockets.ToList())
{
socket.Send(input);
}
input = Console.ReadLine();
}
Is certificate signed by a browser trusted CA? If not, the web page you are opening with Chrome has to be under HTTPS so you can be prompted to accept the certificate, otherwise the connection will fail.
If even doing that does not work, please try with WebSocketListener and tell me which error you get if any.
Some issues I found debugging WSS:
Remember to change the port number to a one different to the one you used for not secure connections. Some browsers get confused if suddenly a port becomes secure or viceversa.
Remember to use the hostname indicated in the certificate to connect and not the IP.
If you are using a self-signed certificate, use it for HTTPS so you can see the dialog for accepting that certificate. When accessing via WSS:// there is not certificate acceptance dialog, it will just fail to connect.
Try with a self-signed certificate as well and see if it works.

Amazon S3 issues getting SSL to work with c# sdk

I'm using the Amazon AWS .NET SDK v1.2.1.
The following code throws an exception after failing a DNS lookup for myBucket.more.https which is clearly not what it should be looking for...
AmazonS3Config S3Config = new AmazonS3Config()
{
ServiceURL = "https://s3.amazonaws.com",
CommunicationProtocol = Amazon.S3.Model.Protocol.HTTPS,
};
using (AmazonS3 client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKey,secretKey, S3Config))
{
PutObjectRequest request = new PutObjectRequest();
using (MemoryStream ms = new MemoryStream(inputBytes))
{
request.WithBucketName("myBucket.more")
.WithKey(output.Name)
.WithInputStream(ms);
using (S3Response response = client.PutObject(request))
{
Log.Message("File Sent: " + output.Name);
}
}
}
If I remove the https:// from the front of the ServiceURL it throws a web exception with:
"The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
So how am I suppose to get SSL working?
The only way I've managed so far is with the following, which is not secure:
AmazonS3Config S3Config = new AmazonS3Config()
{
ServiceURL = "s3.amazonaws.com",
CommunicationProtocol = Amazon.S3.Model.Protocol.HTTP,
};
UPDATE
If I don't pass a custom S3Config to CreateAmazonS3Client, it is still failing with:
"The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
"The remote certificate is invalid according to the validation procedure."
The ServiceUrl should be S3.amazonaws.com without the https:// in front. That is the default setting as is HTTPS for the Communication protocol. That's why you get the same error when you don't set the settings manually.
Update
EU buckets cannot contain periods(.) in the name if you want to use HTTPS.

Categories