locked
Https Client Authentication - How To?

    Question

  • I'm trying to implement Https Client Authentication in my application but I am having trouble finding any documentation on how to do it.

    Looking through the MSDN documents I came up with this

    // Certificate file in DER format (.cer or .p7b)   
    string CountriesFile = @"Assets\https-client.keystore.cer";
    StorageFolder InstallationFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
    StorageFile file = await InstallationFolder.GetFileAsync(CountriesFile);
    
    // Read the file into a buffer
    IBuffer buffer = await Windows.Storage.FileIO.ReadBufferAsync(file);
    
    // Create the Certificate object
    Certificate ClientCert = new Certificate(buffer);
    HttpBaseProtocolFilter aHBPF = new HttpBaseProtocolFilter();
    aHBPF.ClientCertificate = ClientCert;
    
    // Create our http client and send the request.
    HttpClient httpClient = new HttpClient(aHBPF);
    HttpResponseMessage response = await httpClient.SendRequestAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).AsTask(cts.Token);

    I put this code together looking at the docs for HttpClient , HttpBaseProtocolFilter  and Certificate . Making the assumption that I should have the certificate in the required format and read the file into the Certificate class.

    The above code doesn't work and throws this error.

    An exception of type 'System.ArgumentException' occurred in MyLib.DLL but was not handled in user code
    WinRT information: The certificate specified is missing the required private key information

    I have tested my server set-up and it works with client auth through a browser, which leads me to two possible conclusions.

    1. The certificate file is in the wrong format (though I would have hoped the exception would get thrown when the Certificate class is constructed).
    2. This is not intended way to do it!

    Any one know how it should be done?

    Thursday, August 14, 2014 10:12 AM

All replies

  • Hi nezero,

    Your code looks correct, I don't see any problem here.

    May I know how you generate the certification file? Basically Certificate class only accept the blob that generated from GetCertificateBlob | getCertificateBlob method. The question is how you get this certificate file, I may consider the certificate file is in wrong format as your guess.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Monday, August 18, 2014 8:13 AM
    Moderator
  • James,

    Isn't this a catch 22? How can I call getCertificateBlob if I only have a certificate file an not the an Object?

    I've done some more research and the documentation states it needs the certificate in a DER encoded format and the only way I can find that exports my JKS keypair to a DER enconded certificate strips out the private key.

    keytool -exportcert -alias myName -keystore keypair.jks -file keytool_crt.der

    I have found a way to import a .p12 version of my keypair to the UserCertificateEnrollmentManager using ImportPfxDataAsync | importPfxDataAsync methods.

    However, this is not what I want. I don't really want to install the certificate on the machine, I want to make it only available to the application if that is possible. Once its on the machine I can find it using

    CertificateStores.FindAllAsync(new CertificateQuery() { FriendlyName = "MyFriendlyName" });

    Monday, August 18, 2014 8:48 AM