Solved: Identity Server v3 and ‘Invalid provider type specified’ CngKey private key errors

In the scenario described in this post, you have encountered an error in your log that says the following:

Signing certificate has not private key or private key is not accessible. Make sure the account running your application has access to the private key

TL;DR; See how to convert your certificate key from CNG to RSA

Or maybe your haven’t seen this error message but have encountered an issue with Identity Server signing it tokens.  If this is the case, I would highly recommend you stop and enable logging before you go any further, restart your application and check your logs for the error message above.  Logging is key, we need to see what is going on in order to know how to fix it! Jump ahead to Enabling Logging in Identity Server V3 then come back to find out what the error is all about.

Assumptions

Now, this article assumes you have checked some of the obvious things.  Run through the following list and if the answer is “Yes!” for every question then you may proceed 🙂

  • Have you checked that the certificate you are using actually has a private key?
  • Have you checked that the password you are using to access the private key is correct?
  • Have you checked that the account your application is running under has permissions to access to the private key?

OK, so you have answered yes to all of these questions – so it is maybe beginning to be more likely that you are falling foul of a Cng Key issue.

What is a CNG Key?

Certificates in Windows are stored using Storage Providers. Windows has two of these providers, that are not compatible. The old style “Cryptographic Service Providers” or CSP in short and the new style “Cryptography API: Next Generation” or CNG. The CNG providers have been around since Windows Vista, and although it is more secure and easier to use many facets of software are still not compatible with CNG providers.  This appears to also include the .NET Framework.

A possible workaround to this may be to use CryptoAPI/CNG API directly to deal with CNG keys.  But if we want an easier and pure .NET solution which understands CNG, we need to find another solution (details to follow!).

How was my PFX file generated?

In this case, I used the powershell module New-SelfSignedCertificate to generate a self-signed certificate and then exported that certificate to a PFX file via the Management Console.

Proving out the issue

So let’s investigate what’s causing the “Signing certificate has not private key or private key is not accessible” error.

To help me figure this out, I created the following test stub which I used to load a certificate (from an embedded resource in this case) and attempt to access the private key.

Running this code results in the following entries in my log file

Closer inspection of the error thrown when accessing the private key revealed the following exception being thrown.

System.Security.Cryptography.CryptographicException: Invalid provider type specified.
at System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()

Now we seem to be getting somewhere!

GoogleFoo resulted in me discovering Alejandro Magencio’s blog post on this very exception.  His post describes in detail the background to what is going on underneath the covers and why we are getting this exception.

In short, the .NET Framework being used does not like CNG keys.  In order access them we need to either talk directly to the CryptoAPI/CNG API or we could use the CLR Security open source library.

Adding in usage of the CLR Security library allows me to interogate the type of private key that my certificate has.

Which results in the following entries in my log file.

This is great, but I would prefer to not have to code my way out of this.  I would rather have a certificate in a format that can be readily accessed by my .NET code.  So, let’s convert my certificate private key from CNG to RSA.

Converting your certificate key from CNG to RSA

Steps:

  1. Extract your public key and full certificate chain from your PFX file
  2. Extract the CNG private key
  3. Convert the private key to RSA format
  4. Merge public keys with RSA private key to a new PFX file

After changing your application to use the new PFX you just created, you should find that your issues have been resolved.

Now let’s see how to carry out these steps using OpenSSL (Get OpenSSL for Windows from here)

1. Extract your public key and full certificate chain from your PFX file

OpenSSL pkcs12 -in "yourcertificate.pfx" -nokeys -out "yourcertificate.cer" -passin "pass:myreallystrongpassword"

2. Extract the CNG private key

OpenSSL pkcs12 -in "yourcertificate.pfx" -nocerts –out “yourcertificate.pem" -passin "pass:myreallystrongpassword" -passout "pass:myreallystrongpassword"

3. Convert the private key to RSA format

OpenSSL rsa -inform PEM -in "yourcertificate.pem" -out "yourcertificate.rsa" -passin "pass:myreallystrongpassword" -passout "pass:myreallystrongpassword"

4. Merge public keys with RSA private key to a new PFX file

OpenSSL pkcs12 -export -in "yourcertificate.cer" -inkey "yourcertificate.rsa" -out "yourcertificate-converted.pfx" -passin "pass:myreallystrongpassword" -passout "pass:myreallystrongpassword"

Enabling Logging in Identity Server

Identity Server v3 provides a wealth of information to developers through it’s two logging features.  Development time logging provides really low level details to assist developers diagnose issues during development and testing.  Production-time logging comes in the form of a number of events being raised to assist in system monitoring and fault diagnosis.   The reason there are two levels of logging is that it is possible that sensitive information may be exposed through development logging and this facility should therefor always be disabled when the system is in production.

To enable logging with Identity Server v3,

  1. Configure the logging framework of choice. 

For example, you could configure Serilog via the following statement:

  1. Configure Identity Server Logging settings

Here is a full list of the logging settings available for Identity Server V3.

  1. Enable Diagnostic Logging in your application configuration file

For example

As is also recommended by the developers of Identity Server, I use BareTail to provide me with a great view of my log files.

For more details on Identity Server logging configuration, see the official Identity Server v3 documentation

Now that you have configured logging, build and rerun your application and confirm that a log file is being created.  Then check the log file for error.  You may now wish to return to reading about the certificate error upon which this post is based.

Office 2016 Logos

Fix: Blurred text in Office 2016 (Skype for Business 2016)

Example of blurred text in Skype for Business UI

Just a heads up.  If after you install Office 2016 you discover that the Skype For Business UI displays with horrendous burred font and scaling issues, then I may have a fix for you.

The fix is rather simple…

  1. Switch to Outlook
  2. Go to File > Options > Advanced > and Turn off hardware acceleration
  3. Restart Skype for Business 2016

…and your problem should be solved.

DC

HowTo: Clear Nuget cache on a build server

nuget cache clear
teamcity512

Do you need to clear the Nuget cache on a build server which runs as a windows service?
Simply navigate to the nuget cache store which is located in the temp directory for the system service accounts.

Alternatively, you could tell nuget to bypass the nuget cache altogether when it installs packages by using the -nocache option in your install statement

image_thumb.png

HowTo: Use self-signed certificates during Windows Apps development (no code required)

 

TL;DR; My solution was to save my self signed certificate in DER format, sticking it on a local IIS site, loading the URL to the certificate in my mobile emulator, opening the file (when prompted) and installing the certificate.  Having done this, my mobile now trusts that certificate and I am free to play to my hearts content over HTTPS.

Continue reading

HowTo: Auto synchronise files upon network connection (Windows)

TestLab.grid-6x2There are times where we need to work away from the office network and the safety of backup infrastructure.  What would be nice is to automatically synchronise files on my laptop whenever I connect to the office network.

Working locally on laptops, it should go without saying, carries a danger of loosing data either through “Doh!” moments or through hardware failure (travelling can indeed be hard on the little grey rectangular friends of ours) so we need a solution that provides some safety to our data – preferably without us having to remember to do anything.  Holding back the urge to write something bespoke for once I looked at what I already have my dispersal –  GIT, RoboCopy and Task Scheduler to the rescue – Let’s start auto synchronising our files upon connecting to a given network

Continue reading

Designing with Animation

Presentation by Pasquale D’Silva http://psql.me/

We’re in the future, and interfaces are falling behind the curve. Software should feel as responsive and human as the people interacting with it. Design should respond and react with vitality. Too much design is created with an old, static web mentality, and not pushing the new mediums we have to design for. What is it like building interfaces with an animated foundation? Why is it better? This will be an adventure into the magical cosmos of animation. Cartoons, Anvils, Jokes, Jokes people might not get, Dynamite, Stage Dives!

Referenced Article – Transitional Interfaces on Medium

How do I edit my GitHub Wiki locally and include relative images?

This post sets out to describe how to edit a GitHub wiki on your computer as an alternative to editing directly within the GitHub web UI.

Cloning the GitHub Wiki to your computer

The wiki content is unsurprisingly stored within a Git repository and GitHub give you direct access to this repository which can enable you to edit the content locally on your computer. First though we need to clone the git repository to our computer.

  • From your repository homepage on GitHub, click the Wiki link on the right hand side Wiki link example
  • If you already have content in your wiki, Click the Clone URL button.

image

  • If you have yet to create a page on your wiki you only see the green New Page button. Simply click New Page, set a page title (for example Home) and put some filler blurb content in the page body. Hit Save, and the Clone URL button should appear.

Hitting the Clone URL button will copy the git url for your wiki repository into your clipboard.

  • Now, go to your favourite git client and clone the repository to your computer.

Editing your wiki content efficiently (Windows)

GitHub wiki content can be written in a number of different markup languages. My preference is markdown.

For this I use an awesome editor (if I do say so myself) called MarkPad which was one of the projects we worked on as part of the Code52 effort.

MarkPad is available for windows desktop (download) as well as a windows store app (install from Windows Store) – the source is also available for all if you want to have a poke about.

Sidenote: MarkPad is open source and as such is open to contributions from anyone. We are very open to community contributions so if you use it and think of a way to make it even better then please do get in touch via GitHub issues.

Instructions on how to write Markdown is out of the scope of this article but anyone familiar with editors such as MSWord will pick up thinks pretty quickly.

Ok, so one of the best life-hacks (read: makes your life simple) offered by MarkPad is its handling of images. You can of course construct links to images on the web in markdown but what is extra handy is that MarkPad can also generate image files on the fly from your clipboard.

Simply take a screenshot using something like Shotty (copy to clipboard) or Cropper (set output to clipboard)  and Paste (<ctrl>+v) the contents of your clipboard. MarkPad will automatically generate an image file appropriately named for where you pasted within your document (in relation to the closest header) and link to it in markdown. Very cool, very easy.

Note: When linking to images in markdown that have paths relative to the wiki page be sure to use  “\” as the path separator and not “/”

Push your changes to GitHub

Commit your changes, making sure to include (add) any new content and/or images generated then just perform a GIT push to submit your changes to github. Your changes will be visible on the wiki immediately – go marvel in their splendour.

Glimpse for DotNetOpenAuth 1.3

Finally I got a chance tonight to update my DotNetOpenAuth extension for Glimpse. I’ve pushed the update out to Nuget so go ahead and update now.

 

What does it do?

This extension attaches to the internal logging of DotNetOpenAuth and provides you with a view directly within your browser.

Example of Glimpse for DotNetOpenAuth

The source code and test MVC4 web app have been published to GitHub here

https://github.com/DavidChristiansen/DNOA4Glimpse

Glimpse

The guys at Glimpse have put some really amazing work into Glimpse as of late. Check it out if you haven’t already http://getglimpse.com

openid_connect

How simple is a OpenID Connect Basic client? (C#)

John Bradley has just posted a great entry demonstrating how simple life is going to be for a Relying Party when it comes to OpenID Connect. I highly recommend you go and read it.

OpenID Connect provides a lot of advanced facilities to fulfill many additional features requested by the member community. It is full of features that go beyond basic Authentication. However, that does not mean that it cannot be used for the simple case for “Just Authentication”.

The sample code in John’s post is in PHP so I thought I would quickly provide the same samples in C#. here we go.

Making an OpenID Connect request

In order for the client to make an OpenID Connect request, it needs to have the following information about the server:

  • client identifier – An unique identifier issued to the client (RP) to identify itself to the authorization server. (e.g. 3214244)
  • client secret – A shared secret established between the authorization server and client used for signing requests.
  • end-user authorization endpoint – The authorization server’s HTTP endpoint capable of authenticating the end-user and obtaining authorization. (e.g., https://server.example.com/authorize )
  • token endpoint – The authorization server’s HTTP endpoint capable of issuing access tokens.

In the simplest cases, this information is obtained by the client developer, having read the server’s documentation and pre-registered their application. Then, for a bear bone authentication request you would put a link like this in the HTML page:

The user initiates login by clicking on the “Login with Example.com” link, and is taken to the server where she is asked username/password etc. if she is not logged into example.com yet. Once she agrees to login to  the RP, the browser is redirected back to the call back URL at the RP by 302 redirect. The PHP Server side code may look like:

Note: state is the parameter that is used to protect against XSRF.  It binds the request to the browser session.  It is recommended but not required in OAuth and has been omitted to make the example static. That should be simple enough?

Calling the Token endpoint to get id_token

Now that the RP has the ‘code’, you need to get the id_token from the token endpoint. The id_token is the user login information assertion.  What do you do? Just GET it with HTTP Basic Auth using client_id, client_secret, and the code you got in the first step. Using C#, it would look like:

The result, responseJson, will contain a JSON like this (line wraps for display purposes only):

For simple authentication we will ignore “access_token”, “token_type” etc. What you only care about is the “id_token”. “id_token” is encoded in a format called  JSON Web Token (JWT). JWT is the concatenation of “header”, “body”, “signature” by periods (.). Since you are getting this directly through TLS protected channel that is verifying the identity of the server certificate, you do not need to check the signature for integrity, so you just take out the second portion of it and base64url_decode it to get the information out of the id_token. So in c# you may do something like:

The resulting assertion, id_body in the above example,  about the user (after pretty formatting)  is:

“iss” is showing the issuer of this token, in this case, the server.example.com. The issuer must match the expected issuer for the token endpoint, if it is different you must reject the token. the ‘iss” is the name space of the  user_id, which is unique within the issuer and never reassigned. When the client stores the user identifier, it MUST store the tuple of the  user_id and iss. “aud” stands for “audience” and it shows who is the audience of this token. In this case, it is the RP’s client_id. If it is different, you must reject the token. “iat” stands for the time the token was issued.  This can be ignored in this flow as the client is talking directly to the token endpoint. “exp” is the expiry time of the token. If the current time is after “exp”, e.g., in PHP, if  $exp < time();  the RP should reject the token as well. So, that is it. Now you know who is the user, i.e., you have authenticated the user. All of the above in the form of code would be:

— Once again, be sure to go read John’s post (http://www.thread-safe.com/2012/07/how-simple-is-openid-connect-basic.html)

Solved: Chrome v18, self signed certs and “signed using a weak signature algorithm”

So chrome has just updated itself automatically and you are now running v18 – great. Or is it…

If like me, you are someone that are running sites using a self-signed SSL Certificate (i.e. when running a site on a developer machine) you may come across the following lovely message;

WAT? Try explaining what a weak signature algorithm means to a non-tech!

Fear not, this is likely as a result of you following instructions you found on the apache openssl site which results in a self signed cert using the MD5 signature hashing algorithm.

Using OpenSSL

The simple fix is to generate a new certificate specifying to use the SHA512 signature hashing algorithm, like so;

Simples!

Now, you should be able to confirm the signature algorithm used is sha512 by looking at the details tab of certificate

Confirming the signature algorithm

Notes

  • If you change your certificate, be sure to reapply any private key permissions you require – such as allowing access to the application pool user.