Search code examples
javac#xamarinxamarin.androidandroid-keystore

How can I use an X.509 certificate with private key from the android keychain in C#/Xamarin?


I'm building a Xamarin app that should load X.509 certificates and RSA public keys from the Android keychain. I want to convert them to an instance of X509Certificate2 (System.Security.Cryptography.X509Certificates.X509Certificate2), but I don't really know how to do this.

I was able to access both certificate chain (java.security.cert.X509Certificate[]) and private key (java.security.IPrivateKey), but I can't combine them to a X509Certificate2. I found this old thread, where the author had a similar problem, but there wasn't really a solution for his problem.

This is the code used by him (doesn't work anymore since Android 4.1. Also, I don't know which PKCS8 class he used, as Mono.Security.Cryptography.PKCS8 is not public):

X509Certificate[] certChain = KeyChain.GetCertificateChain(ctx, Alias);
IPrivateKey privKey = KeyChain.GetPrivateKey(ctx, Alias);

KeyStore pkcs12KeyStore = KeyStore.GetInstance("PKCS12");
pkcs12KeyStore.Load(null, null);
pkcs12KeyStore.SetKeyEntry(Alias, privKey, null, certChain);

X509Certificate javaCertificate = (X509Certificate) pkcs12KeyStore.GetCertificate(Alias);

PKCS8.PrivateKeyInfo privateKeyInfo = new PKCS8.PrivateKeyInfo(privKey.GetEncoded());
RSA privatekeyRsa = PKCS8.PrivateKeyInfo.DecodeRSA(privateKeyInfo.PrivateKey);

X509Certificate2 certificate = new X509Certificate2(javaCertificate.GetEncoded());
certificate.PrivateKey = privatekeyRsa;

Starting in Android 4.1, privKey.GetEncoded() returns null, so I can't use this way and therefore don't know how to get the private key into certificate.

So, the question is: How can I create a X509Certificate2 with the KeyChain API?

Thanks in advance.


Solution

  • The short answer is you can't. It's because the private key is stored in hardware and from Android 4.1, inaccessible to your app, that's why it returns null. Here's an article in case you want to read about it more.