How to view a certificate programatically (C#)

Hi all,

The following C# sample shows a dialog to view a certificate and its properties. This is the same dialog that appears when we double-click on the cert file in Explorer. I’ll use CryptUIDlgViewCertificate API and its CRYPTUI_VIEWCERTIFICATE_STRUCT structure to achieve this:

using System.Security.Cryptography.X509Certificates;
using System.Runtime.InteropServices;

namespace MyNamespace
public partial class MyClass

public const int CRYPTUI_DISABLE_ADDTOSTORE = 0x00000010;

[DllImport(“CryptUI.dll”, CharSet = CharSet.Auto, SetLastError = true)]
public static extern Boolean CryptUIDlgViewCertificate(
ref bool pfPropertiesChanged

public int dwSize;
public IntPtr hwndParent;
public int dwFlags;
public String szTitle;
public IntPtr pCertContext;
public IntPtr rgszPurposes;
public int cPurposes;
public IntPtr pCryptProviderData; // or hWVTStateData
public Boolean fpCryptProviderDataTrustedUsage;
public int idxSigner;
public int idxCert;
public Boolean fCounterSigner;
public int idxCounterSigner;
public int cStores;
public IntPtr rghStores;
public int cPropSheetPages;
public IntPtr rgPropSheetPages;
public int nStartPage;

private void MySampleFunction()
// Get the cert
X509Certificate2 cert = new X509Certificate2(@”C:\temp\mycert.cer”);

// Show the cert
certViewInfo.dwSize = Marshal.SizeOf(certViewInfo);
certViewInfo.pCertContext = cert.Handle;
certViewInfo.szTitle = “Certificate Info”;
certViewInfo.nStartPage = 0;
bool fPropertiesChanged = false;
if (!CryptUIDlgViewCertificate(ref certViewInfo, ref fPropertiesChanged))
int error = Marshal.GetLastWin32Error();

I hope this helps.



Alex (Alejandro Campos Magencio)

Comments (10)

  1. Dave Brown says:


    Very interesting code you have. I am wanting to one, detect the card, two, have a user enter a pin, and lastly, I want to read the card user information, which I will validate via other methods.

    Will your sample, with some tweaking, allow me to do this?

    Thanks in advance for your input!


  2. J-Rod says:

    I need to access a CTL on an IIS server using C#.  I have been looking at your P/Invoke examples and I can probably do it using that.  However, our customer has some concerns with using unmanaged code.  I have been unable to get to the CTL using the X509 objects that I am aware of.  Is there a way to access the CTL (assuming I know which store it is in and I know the CTL identifier from the SSLCtlIdentifier and SSLCtlStore values from AD/WMI).  I just need to verify that the CTL contains certain roots and I can’t seem to find a way to access it using C#.  

    The tool ssldiag.exe from MS shows the contents of the CTL, but I am not sure how it is implemented.  I would like to do it in C# without having to use P/Invoke if at all possible.

    Thanks in advance for any help you can provide.

  3. giedrioks says:

    I can’t get this code working in VB.NET environment. I wrote such a code in VB.NET, but when I call CryptUIDlgViewCertificate() application throws an exception. I would be very thankful if you could try to do this in VB.NET and post here if it works. I could send you my code to review, but don’t know your e-mail.

  4. blehrg says:

    Certificate2 cert = new X509Certificate2(@"C:tempmycert.cer");


  5. giedrioks says:

    Yes, thanks. This one works well. Just need to mention, that reference to "" should be added in VB.NET.

  6. Borce Kocevski says:

    We are trying to automate importing of contacts to Outlook (both 2003 and 2007).

    Basically we read the contact details from a DB or csv file and create the contact items using C# code.

    In a folder we also have contact's certificate files that we would like to attach to the above created contacts in code.

    We have a code for Outlook 2007 that uses propertyaccessor and which does the import with no reported errors. However when we open Outlook contacts manually, there are no certificates attached!

    Tot troubleshoot, we compared, byte by byte, the certificate that we import via code and the same certificate that is manually attached to a contact.

    They differ for few bytes both at the begining and at the end!

    It seems that Outlook adds some header and footer bytes to the attached certificate when we import it manually.

    If we artificially add those header and footer bytes to our certificate in code, it will be imported and shown later in Outlook just fine!

    However these header/footer bytes seem to be certificate related and are not the same for every certificate. Just their total number is the same.

    The question now is, how can we determine the process of adding these extra bytes before and after the certificate so it is always recognized by Outlook?

    We searched on the internet a lot in regards to this problem but so far no solution was found.

    I hope you can give us a clue on this?

  7. Sorry, I don't know what outlook does, as I don't the product to that extent…

  8. Spitz says:

    How do you display the dialog as a Modal Dialog as you can return to the main application and just keep clicking button to view certificates, not a good idea?

  9. Hi Spitz,

    Never tried it, but does it help if you pass a valid window handle in hwndParent param of the CRYPTUI_VIEWCERTIFICATE_STRUCT struct?

  10. Spitz says:

    Yes, it does!

    Though I worked this one out myself and only came here to update my findings lol

    certViewInfo.hwndParent = this.Handle;