First of all the title of the question may seem like a duplicate. But I tried all possible solutions at SO and nothing works. Most interestingly the same code is working for .net framework-4.x.
The certificate and the key is valid as the same code with same .crt and .key is working.
var certPath = _fileProvider.Combine(_fileProvider.MapPath("~/Plugins/Payments.CityBankApi/"), "othoba.crt");
var keyPath = _fileProvider.Combine(_fileProvider.MapPath("~/Plugins/Payments.CityBankApi/"), "othoba.key");
string certificateText = File.ReadAllText(certPath);
string privateKeyText = File.ReadAllText(keyPath);
ICertificateProvider provider = new CertificateFromFileProvider(certificateText, privateKeyText, true);
var certificate = provider.Certificate;
string accessTokenUrl = string.Empty;
accessTokenUrl = "https://sandbox.thecitybank.com:7788/transaction/token";
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(certificate);
handler.ServerCertificateCustomValidationCallback +=(sender, certificate, chain, errors) => {
return true;
};
string json = JsonConvert.SerializeObject(new
{
userName = _cityBankPaymentSettings.UserName,
password = _cityBankPaymentSettings.Password
});
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var client = new HttpClient(handler);
var result = client.PostAsync(accessTokenUrl, httpContent).GetAwaiter().GetResult();
try
{
var pfxPath = _fileProvider.Combine(_fileProvider.MapPath("~/Plugins/Payments.CityBankApi/"), "othoba.pfx");
var certPath = _fileProvider.Combine(_fileProvider.MapPath("~/Plugins/Payments.CityBankApi/SandBoxCrt/"), "othoba.crt");
var keyPath = _fileProvider.Combine(_fileProvider.MapPath("~/Plugins/Payments.CityBankApi/SandBoxCrt/"), "othoba.key");
string tokenUrl = "https://ecomm-webservice.thecitybank.com:7788/transaction/token";
string crtPassword = _cityBankPaymentSettings.CrtPasswordProduction;
if (!_cityBankPaymentSettings.ProductionMode)
{
tokenUrl = "https://sandbox.thecitybank.com:7788/transaction/token";
crtPassword = _cityBankPaymentSettings.CrtPasswordSandBox;
pfxPath = _fileProvider.Combine(_fileProvider.MapPath("~/Plugins/Payments.CityBankApi/SandBoxCrt/"), "createorder.pfx");
certPath = _fileProvider.Combine(_fileProvider.MapPath("~/Plugins/Payments.CityBankApi/SandBoxCrt/"), "createorder.crt");
keyPath = _fileProvider.Combine(_fileProvider.MapPath("~/Plugins/Payments.CityBankApi/SandBoxCrt/"), "createorder.key");
}
var certificate = await LoadPemCertificate(certPath, keyPath);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(certificate);
handler.ServerCertificateCustomValidationCallback = (e, r, c, n) => true;
string json = JsonConvert.SerializeObject(new
{
userName = _cityBankPaymentSettings.UserName,
password = _cityBankPaymentSettings.Password
});
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var client = new HttpClient(handler);
var result = await client.PostAsync(tokenUrl, httpContent);
var jsonString = await result.Content.ReadAsStringAsync();
cityBankAccessToken = JsonConvert.DeserializeObject<CityBankAccessTokenResponeModel>(jsonString);
await _logger.InformationAsync("cityBankAccessToken:" + cityBankAccessToken);
}
catch (Exception ex)
{
await _logger.ErrorAsync("CityResponseAccessTokenExc:" + ex.Message, ex);
}
Load Certificate method.
public async Task<X509Certificate2> LoadPemCertificate(string certificatePath, string privateKeyPath)
{
using var publicKey = new X509Certificate2(certificatePath);
var privateKeyText = await File.ReadAllTextAsync(privateKeyPath);
var privateKeyBlocks = privateKeyText.Split("-", StringSplitOptions.RemoveEmptyEntries);
var privateKeyBytes = Convert.FromBase64String(privateKeyBlocks[1]);
using var rsa = RSA.Create();
if (privateKeyBlocks[0] == "BEGIN PRIVATE KEY")
{
rsa.ImportPkcs8PrivateKey(privateKeyBytes, out _);
}
else if (privateKeyBlocks[0] == "BEGIN RSA PRIVATE KEY")
{
rsa.ImportRSAPrivateKey(privateKeyBytes, out _);
}
var keyPair = publicKey.CopyWithPrivateKey(rsa);
var Certificate = new X509Certificate2(keyPair.Export(X509ContentType.Pfx));
return Certificate;
}
For Linux(Ubuntu 20.04)
Adding this to the top of /etc/ssl/openssl.cnf:
openssl_conf = default_conf
and this to the bottom of it:
[default_conf]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT:@SECLEVEL=1