Daniel Lozano
Daniel Lozano

Reputation: 569

Two way SSL X509 Certificate location for secure service request in .Net Core MVC - Azure Services Hosted application

I've being working with x509 certificates in order to make secure requests to some data services. They require Two way SSL auth, so I've converted my "Sandbox" certificate (.crt) w/ my Private Key to a Password protected .p12 file.

Here's the first question: Where should I place this .p12 file so that it's readable by my application after deploying to Azure (Using DevOps) but still stored securely? Can I use an my Azure Key Vault?

The second issue is that in my Dev environment I haven't been able to establish the SSL binding after making the request (With a .p12 absolute path):

Here's the code I'm using:

void GetATMs()
    {
        string requestURL = "https://sandbox.api.visa.com/globalatmlocator/v1/localatms/atmsinquiry";
        string userId = "MyUserId";
        string password = "MyPassword";
        string p12certificatePath = "C:\\Code\\projects\\project\\\\Clients\\PaymentGateways\\Visa\\Certs\\TC_keyAndCertBundle.p12";
        string p12certificatePassword = "CertPassword";
        string postData = @"{""wsRequestHeaderV2"": { ""requestTs"": ""2018-11-06T03:16:18.000Z"", ""applicationId"": ""VATMLOC"", ""requestMessageId"": ""ICE01-001"", ""userId"": ""CDISIUserID"", ""userBid"": ""10000108"", ""correlationId"": ""909420141104053819418"" }, ""requestData"": { ""culture"": ""en-US"", ""distance"": ""20"", ""distanceUnit"": ""mi"", ""metaDataOptions"": 0, ""location"": { ""address"": null, ""placeName"": ""700 Arch St, Pittsburgh, PA 15212"", ""geocodes"": null }, ""options"": { ""range"": { ""start"": 10, ""count"": 20 }, ""sort"": { ""primary"": ""city"", ""direction"": ""asc"" }, ""operationName"": ""or"", ""findFilters"": [ { ""filterName"": ""OPER_HRS"", ""filterValue"": ""C"" } ], ""useFirstAmbiguous"": true } } }";

        HttpWebRequest request = WebRequest.Create(requestURL) as HttpWebRequest;
        request.Method = "POST";
        // Add headers
        string authString = userId + ":" + password;
        var authStringBytes = System.Text.Encoding.UTF8.GetBytes(authString);
        string authHeaderString = Convert.ToBase64String(authStringBytes);
        request.Headers["Authorization"] = "Basic " + authHeaderString;
        // Add certificate
        var certificate = new X509Certificate2(p12certificatePath, p12certificatePassword);

        request.ClientCertificates.Add(certificate);
        request.Accept = "application/json";
        var data = Encoding.ASCII.GetBytes(postData);
        request.ContentLength = data.Length;
        // Get the request stream.  
        Stream dataStream = request.GetRequestStream();
        // Write the data to the request stream.  
        dataStream.Write(data, 0, data.Length);
        // Close the Stream object.  
        dataStream.Close();
        // Get the response.  
        WebResponse response = request.GetResponse();
        // Display the status.  
        Console.WriteLine(((HttpWebResponse)response).StatusDescription);
        // Get the stream containing content returned by the server.  
        dataStream = response.GetResponseStream();
        // Open the stream using a StreamReader for easy access.  
        StreamReader reader = new StreamReader(dataStream);
        // Read the content.  
        string responseFromServer = reader.ReadToEnd();
        // Display the content.  
        Console.WriteLine(responseFromServer);
        // Clean up the streams.  
        reader.Close();
        dataStream.Close();
        response.Close();

What am I missing here?

It fails the following way:

An unhandled exception occurred while processing the request.
Win32Exception: The credentials supplied to the package were not recognized
System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface secModule, string package, CredentialUse intent, SCHANNEL_CRED scc)

HttpRequestException: The SSL connection could not be established, see inner exception.
System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)

WebException: The SSL connection could not be established, see inner exception. The credentials supplied to the package were not recognized
System.Net.HttpWebRequest.GetResponse()

We have a Wildcard SSL for our domain. Are they different? Can it be registered in the Visa dashboard and used for make secure request as it is signed by a trusted CA authority?

Upvotes: 1

Views: 438

Answers (1)

Daniel Lozano
Daniel Lozano

Reputation: 569

Well, yes. As per, @dagope Recommendation, I've uploaded my certificate to key-management on Azure and access it through the SDK. This is also a best practice for key/certificate management on Azure.

Upvotes: 1

Related Questions