Contents

Storing certificates more securely when using Google APIs, OAuth 2.0 and .Net

Contents

Recently, I’ve been replacing bit.ly with the Google URL shortener service for a .Net project. It’s a pretty simple service, and the documentation shows very clearly how to get going.

Google have 3 different ways of authenticating using OAuth 2.0 (details), the method I am using is as a “Service Account”. Their code sample is thus:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
String serviceAccountEmail = "SERVICE_ACCOUNT_EMAIL_HERE";
var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable);
 
ServiceAccountCredential credential = new ServiceAccountCredential(
  new ServiceAccountCredential.Initializer(serviceAccountEmail)
  {
    Scopes = new[] { PlusService.Scope.PlusMe }
  }.FromCertificate(certificate));
 
// Create the service.
var service = new UrlshortenerService(new BaseClientService.Initializer()
{
  HttpClientInitializer = credential,
  ApplicationName = "API Sample",
});

The key thing that I want to draw your attention to is line 2, this implies (to me) that you are probably goign to keep the certificate in source control along with your code. This isn’t good, as it could lead quite easily to mistakenly making it public (e.g. pushing the project to GitHub).

A better solution would be to attempt to load the certificate from the local certificate store on the machine.

So that means that line 2 above, would be replaced with the following:

1
2
3
4
5
6
string certificateIssuerName = "blahblahblah123456.apps.googleusercontent.com";
 
X509Store store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var cert = store.Certificates.Find(X509FindType.FindByIssuerName, certificateIssuerName, false)[0];
store.Close();

Things to know:

  1. NB: Very important, you need to make sure you call the Open method on the store, otherwise you will find that calling the Find method will never return you a certificate.
  2. When importing the certificate into your certificate store, make sure you include the private key, otherwise your code won’t work.