Andrew Arnott
Andrew Arnott

Reputation: 81791

How to read public key from PFX file without the password in .NET

I need to be able to read the public key from a PFX file without knowing its password. I'm pretty sure only the private key is encrypted, but all the convenient APIs that read the PFX format seem to be broken without a password even if I don't need the private key.

Any ideas how to read the public key?

Upvotes: 0

Views: 1093

Answers (1)

Χpẘ
Χpẘ

Reputation: 3451

I looked into this a while to see if I could determine how the Cert Manager is able to open a PFX file. What I found is that cryptext.dll is the "Crypto Shell Extensions" and handles PFX files. If you search the registry for cryptext.dll you'll see that it handles a lot of different file types (CERs, CRLs, crypto store, etc.). It is invoked using rundll32.exe along with a "verb". From the registry you can see which verb is associated with each file type.

Cryptext.dll is a COM component. Although it contains an embedded typelib, using TLBIMP to create an interop assembly doesn't provide access to any interesting methods or properties. Based on OLEVIEW, it only implements the IUnknown interface. So there's no obvious way to programmatically access it from .NET or from an unmanaged program.

The fact that it is a COM component means it is (almost surely) using unmanaged crypto APIs.

Here are a couple of suggestions on reverse engineering cryptext.dll to see how it works. Dump the ASCII/UNICODE strings in the file. You should see the various verbs indicated above. Determine which verb(s) is most likely to support opening PFX files. Try running rundll32.exe using the verb(s) you pick with a PFX as input. Hopefully you'll figure out which is the right verb.

Then load rundll32.exe into a debugger (ie Windbg). Set the command line in the debugger to use the verb you found as well as your test PFX file. Put a read breakpoint within the DLL's memory on the first byte/word of the string containing that verb. (You can search memory with windbg). Then start execution. When the read breakpoint triggers, start stepping through the code that read the string. It will probably be in a loop comparing the verb specified on the command line with each verb within the program. It should be in the middle of comparing the verb in question. Therefore it should exit the comparison loop and go to a handler for that verb. Step into that handler and see what crypto APIs it calls. Knowing the crypto APIs will hopefully be enough to figure out how to access the public key in the PFX file.

Upvotes: 2

Related Questions