I need to login to my server via https put request. I have the certificate and key in my project but I still can’t seem to be able to login. My current code:
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using Newtonsoft.Json;
namespace MyProject
{
public class Login : Window
{
private TextBox ipAddressBox;
private TextBox usernameBox;
private PasswordBox passwordBox;
private Button loginButton;
private Button cancelButton;
private ProgressBar progressBar;
public Login()
{
Title = "Login";
Width = 300;
Height = 400;
WindowStartupLocation = WindowStartupLocation.CenterScreen;
var border = new Border
{
Padding = new Thickness(10),
Child = CreateStackPanel()
};
Content = border;
}
private StackPanel CreateStackPanel()
{
var stackPanel = new StackPanel();
var image = new Image
{
Source = new BitmapImage(new Uri("pack://application:,,,/MyProject;component/Assets/my_picture.png")),
Height = 100,
Margin = new Thickness(0, 0, 0, 10)
};
stackPanel.Children.Add(image);
stackPanel.Children.Add(new Label { Content = "IP Address:" });
ipAddressBox = new TextBox();
stackPanel.Children.Add(ipAddressBox);
stackPanel.Children.Add(new Label { Content = "Username:" });
usernameBox = new TextBox();
stackPanel.Children.Add(usernameBox);
usernameBox.ToolTip = "username";
stackPanel.Children.Add(new Label { Content = "Password:" });
passwordBox = new PasswordBox();
stackPanel.Children.Add(passwordBox);
loginButton = new Button { Content = "Login", Margin = new Thickness(0, 10, 0, 0) };
loginButton.Click += LoginButton_Click;
stackPanel.Children.Add(loginButton);
cancelButton = new Button { Content = "Cancel", Margin = new Thickness(0, 10, 0, 0) };
cancelButton.Click += CancelButton_Click;
stackPanel.Children.Add(cancelButton);
progressBar = new ProgressBar { Visibility = Visibility.Hidden, Margin = new Thickness(0, 10, 0, 0) };
stackPanel.Children.Add(progressBar);
return stackPanel;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
private async void LoginButton_Click(object sender, RoutedEventArgs e)
{
string ipAddress = ipAddressBox.Text;
string username = usernameBox.Text;
string password = passwordBox.Password;
if (ValidateIpAddress(ipAddress) && !string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
{
progressBar.Visibility = Visibility.Visible;
string jsonResponse = await PerformLogin(ipAddress, username, password);
progressBar.Visibility = Visibility.Hidden;
MessageBox.Show(jsonResponse);
Close();
}
else
{
MessageBox.Show("Enter valid IP address, username and password");
}
}
private bool ValidateIpAddress(string ip)
{
return IPAddress.TryParse(ip, out _);
}
private async Task<string> PerformLogin(string serverIP, string username, string password)
{
try
{
// Load the certificate and private key from the Certs class
X509Certificate2 clientCert = LoadCertificate(Certs.certPem, Certs.certKey);
// Ensure the correct TLS version is used
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
using (HttpClientHandler handler = new HttpClientHandler())
{
handler.ClientCertificates.Add(clientCert);
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => true;
using (HttpClient client = new HttpClient(handler))
{
var json = new
{
username = username,
password = password,
is_start_up = true
};
string jsonString = JsonConvert.SerializeObject(json);
var content = new StringContent(jsonString, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PutAsync($"https://{serverIP}:8443/login", content);
if (response.IsSuccessStatusCode)
{
string responseContent = await response.Content.ReadAsStringAsync();
var headers = response.Headers;
// Here, handle the response, extract tokens and update your application state
return "Logged in!";
}
else
{
string errorContent = await response.Content.ReadAsStringAsync();
return $"Login failed: {response.ReasonPhrase} - {errorContent}";
}
}
}
}
catch (HttpRequestException httpRequestEx)
{
return $"HttpRequestException: {httpRequestEx.Message}n{httpRequestEx.InnerException?.Message}";
}
catch (Exception ex)
{
return $"Exception: {ex.Message}n{ex.StackTrace}";
}
}
private X509Certificate2 LoadCertificate(string certPem, string keyPem)
{
// Load the certificate
byte[] certBuffer = Convert.FromBase64String(PemToBase64(certPem));
var cert = new X509Certificate2(certBuffer);
// Load the private key
byte[] keyBuffer = Convert.FromBase64String(PemToBase64(keyPem));
RSA rsa = CreateRsaProviderFromPrivateKey(keyBuffer);
// Combine into a single X509Certificate2 object
return cert.CopyWithPrivateKey(rsa);
}
private static string PemToBase64(string pem)
{
return pem
.Replace("-----BEGIN CERTIFICATE-----", "")
.Replace("-----END CERTIFICATE-----", "")
.Replace("-----BEGIN RSA PRIVATE KEY-----", "")
.Replace("-----END RSA PRIVATE KEY-----", "")
.Replace("n", "")
.Replace("r", "");
}
private RSA CreateRsaProviderFromPrivateKey(byte[] privateKey)
{
var rsaParameters = new RSAParameters();
using (var ms = new MemoryStream(privateKey))
{
using (var reader = new BinaryReader(ms))
{
byte bt = 0;
ushort twobytes = 0;
twobytes = reader.ReadUInt16();
if (twobytes == 0x8130) reader.ReadByte();
else if (twobytes == 0x8230) reader.ReadInt16();
else throw new Exception("Unexpected value in private key");
twobytes = reader.ReadUInt16();
if (twobytes != 0x0102) throw new Exception("Unexpected version");
bt = reader.ReadByte();
if (bt != 0x00) throw new Exception("Unexpected value in private key");
rsaParameters.Modulus = reader.ReadBytes(GetIntegerSize(reader));
rsaParameters.Exponent = reader.ReadBytes(GetIntegerSize(reader));
rsaParameters.D = reader.ReadBytes(GetIntegerSize(reader));
rsaParameters.P = reader.ReadBytes(GetIntegerSize(reader));
rsaParameters.Q = reader.ReadBytes(GetIntegerSize(reader));
rsaParameters.DP = reader.ReadBytes(GetIntegerSize(reader));
rsaParameters.DQ = reader.ReadBytes(GetIntegerSize(reader));
rsaParameters.InverseQ = reader.ReadBytes(GetIntegerSize(reader));
}
}
var rsa = RSA.Create();
rsa.ImportParameters(rsaParameters);
return rsa;
}
private int GetIntegerSize(BinaryReader reader)
{
byte bt = 0;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = 0;
bt = reader.ReadByte();
if (bt != 0x02) return 0;
bt = reader.ReadByte();
if (bt == 0x81) count = reader.ReadByte();
else if (bt == 0x82)
{
highbyte = reader.ReadByte();
lowbyte = reader.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt;
}
while (reader.ReadByte() == 0x00)
{
count -= 1;
}
reader.BaseStream.Seek(-1, SeekOrigin.Current);
return count;
}
}
}
With this code I get: “HttpRequestException: An error occurred while sending the request.
The request was aborted: Could not create SSL/TLS secure channel.”
Why could this be and how to fix this?