GetPublicKey to get RSACryptoProvider

Oct 13, 2012 at 9:29 AM

Hello guys,

I have a X509Certificate object (only with public key) and I would like to get its public key as a RSA object in order to sign a given string.

Can you help me out on doing this?

Many thanks,

Ben

Oct 16, 2012 at 9:17 PM
Edited Oct 16, 2012 at 9:18 PM

Ben -

When you say you have an "X509Certificate Object", do you actually mean you have an instance of X509Certificate in .NET or do you mean you have a .pfx or other file that contains your certificate data?  If it's the class object you can use the .GetPublicKey method to get the public key:

var pubkey = cert.GetPublicKey();


If you're looking to get that public key then into your Silverlight or phone app there are a couple of things you can do.  You can base-64 encode that key and either store it with or in your assembly as a variable, or you could retrieve it via a service call.  Then load it into Scrypt with the RsaParameters object.

If you're signing / verifying using the certificate, make sure you also know what hashing algorithm is being used.  There's also a method to return that from teh X509Certificate instance.

You could also use:

var pubkey = cert.GetPublicKeyString();

http://msdn.microsoft.com/en-us/library/9yc7tebx.aspx

Oct 23, 2012 at 11:49 AM

Hi Dustin,

 

Thanks for the answer!

I went close to your findings, but figured out that I need to actually load an existing PFX file from a resource (string) into a RSACrypto object.

It is working on phone when using a Xml string outputted from a console app using X509Certificate2 object, but here I would like to know if there is a better way to just get this PFX file straight into the RSACrypto object to sign some content.

Cheers,

Ben

Oct 23, 2012 at 2:17 PM

Ben -

The library doesn't currently support PFX files directly, only RSA with the properly formatted XML or by populating an RSAParameters object.  One thing you'd want to be careful of too is making sure your PFX that you're loading only contains the public key as you don't want to expose the private key. 

There are a couple of ways you could go about loading the PFX info.  One would be to just serve back the XML from a web service and connect to it with your app.  The benefit of this is that you're not storing it as a resource and you can change or version that key at a later date if you want.  The drawback is that you have to have the service and you create an extra dependency on that service, so if that service ever goes down your app may not function properly unless you've accounted for it.

You could also use SQL Compact to store the key.  This gives you the benefit of being able to combine methods.  You could store the original xml as a resource and push it to the SQL Compact database when your app first runs, or you could pull the key originally from a web service and store it.  I would probably take one of these routes.

Lastly though, what you could do is write an extension to Scrypt that would allow you to process PFX files since the source is available.  If you'd like to write something and contribute it I'd be happy to evaluate it and add it to the library, and give you proper credit as a contributor of course.  If you think this is the best route, one thing you might look into is whether you can use a PEM file instead of PFX.  PFX is a binary encoded file, while PEM is a base64 encoded certificate file with markers that would make it much easier to parse.

I'd have to do a lot of digging to find details on the PFX format as I'm not sure how the data is actually stored and what markers they use to separate it.

Oct 23, 2012 at 2:33 PM

Ben -

I might be able to do you one better :)  The X509Certificate class is supported in Windows Phone 7:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate(v=vs.95).aspx

I was also thinking... are you developing this solely for the phone or also for the browser?  If you're only using it for the phone, Microsoft's built in RSACryptoServiceProvider was added in the Mango (7.1) update.  Microsoft's built in provider has access to resources that my library doesn't since Silverlight doesn't have a SecureString object... the built in provider can store key data in secure memory.  I haven't benchmarked performance between my library and Microsoft's... I know the BigInteger code I'm using performs much faster than Microsoft's in the cases we needed, however they make have some additional optimizations that make the native RSACryptoServiceProvider perform faster.  If you're using Silverlight in the browser, then there is no native option, but if this is for phone only, I would suggest using Microsoft's implementation.  It was added after Scrypt was created.

Thanks,

Dustin

Oct 24, 2012 at 12:52 PM

Hello Justin,

I am using this only on the phone, not in the browser :)

What I am trying to achieve is to sign some content on phone with a private key, to then verify the request server side to validate identity of the user. Thats is why I am trying to read the private key from a PFX file on the phone; the X509Certificate class doesn't give anything to manipulate private keys in certificates, that's why I was trying to use your solution :)

Cheers, Ben

Oct 24, 2012 at 2:16 PM

Ben -

Thanks for the info, I wasn't aware you couldn't do the key modification with the X509 class.  Either way, you could still use the built in RSACryptoServiceProvider if you end up sticking with the XML route.  In my library I used the same XML format as the Microsoft provided cryptography provider so the same XML will work for both.