Decrypt my World

Cryptography, Security, Debugging and more!

How to import a certificate without user interaction (C++ & C#)

How to import a certificate without user interaction (C++ & C#)

Rate This
  • Comments 16

Hi, welcome back,

Today I'm posting a CryptoAPI sample which uses CryptUIWizImport to import a certificate without any user interaction:

 

<SAMPLE Language="C++">

CRYPTUI_WIZ_IMPORT_SRC_INFO importSrc;
memset(&importSrc, 0, sizeof(CRYPTUI_WIZ_IMPORT_SRC_INFO));
importSrc.dwSize = sizeof(CRYPTUI_WIZ_IMPORT_SRC_INFO);
importSrc.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_FILE;
importSrc.pwszFileName = L"C:\\PathToPFX\\cert.pfx";
importSrc.pwszPassword = L"PasswordToDecryptPFX";
importSrc.dwFlags = CRYPT_EXPORTABLE | CRYPT_USER_PROTECTED;
 
if (CryptUIWizImport(
  CRYPTUI_WIZ_NO_UI,
  NULL,
  NULL,
  &importSrc,
  NULL
) == 0)
{
  printf("CryptUIWizImport error 0x%x\n", GetLastError());
}

</SAMPLE>

<SAMPLE Language="C#">

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
 
namespace ImportCertNet
{
    class Program
    {
        public struct CRYPTUI_WIZ_IMPORT_SRC_INFO
        {
            public Int32 dwSize;
            public Int32 dwSubjectChoice;
            [MarshalAs(UnmanagedType.LPWStr)]public String pwszFileName;
            public Int32 dwFlags;
            [MarshalAs(UnmanagedType.LPWStr)]public String pwszPassword;
        }
 
        [DllImport("CryptUI.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern Boolean CryptUIWizImport(
            Int32 dwFlags,
            IntPtr hwndParent,
            IntPtr pwszWizardTitle,
            ref CRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc,
            IntPtr hDestCertStore
        );
 
        public const Int32 CRYPTUI_WIZ_IMPORT_SUBJECT_FILE = 1;
        public const Int32 CRYPT_EXPORTABLE = 0x00000001;
        public const Int32 CRYPT_USER_PROTECTED = 0x00000002;
        public const Int32 CRYPTUI_WIZ_NO_UI = 0x0001;
 
        static void Main(string[] args)
        {
              CRYPTUI_WIZ_IMPORT_SRC_INFO importSrc = new CRYPTUI_WIZ_IMPORT_SRC_INFO();
              importSrc.dwSize = Marshal.SizeOf(importSrc);
              importSrc.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_FILE;
              importSrc.pwszFileName = "C:\\alex.pfx";
              importSrc.pwszPassword = "password";
              importSrc.dwFlags = CRYPT_EXPORTABLE | CRYPT_USER_PROTECTED;
 
              if (!CryptUIWizImport(
                CRYPTUI_WIZ_NO_UI,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    ref importSrc,
                    IntPtr.Zero
              ))
              {
                    Console.WriteLine("CryptUIWizImport error " + Marshal.GetLastWin32Error());
              }
 
              Console.WriteLine("<< Press any key to continue >>");
              Console.ReadKey();
        }
    }
}

</SAMPLE>

 

Note: if you enable High protection mode for the private keys of the certificates via policy, when installing a cert in a machine you will be requested for a password which will be used every time the private key is accessed. When using CryptUIWizImport, a dialog will appear requesting us to enter the High protection password, even if we said we don’t want any UI.

I hope this helps.

Cheers,

 

Alex (Alejandro Campos Magencio)

  • Hi,

    Very interesting article! I'm in need of something similar. I want to export a private key from a certificate using C#.net. The problem is that I don't want that dialog box to appear when accessing the private key, but supply the password in code. Could I use the same approach as the code above?

    If so, do you have me some hints for me? I don't have any experience on P/invoke what so ever :s

  • Do you have High protection mode enabled for your private keys?

  • Yes, that's the reason I get dialog box. I'd like to export the certificate keys to a RSAParameters-object.

    Turning high protection off is one solution, but then the security of the certificates on server-side is compromised...

  • Sorry, I haven't seen a way to pass the high protection password programmatically, with any CryptoAPI I've ever used. You should have the same issues I commented with CryptUIWizImport in the article above.

  • Using the above code I still get a security warning box..asking me If I would want to install the certificate or not..

    Please tell how to do away with this..

  • Hi Alam,

    I don't know right now why you may be getting that security warning box. CRYPTUI_WIZ_NO_UI should get rid of it. If it doesn't maybe you can open a case with us, Technical Support, and we'll be more than happy to assist you.

    Cheers,

    Alex

  • This is exactly what I am looking for, however, I need to code it using VBA.  Is this possible?

  • Hi,

    i've done something similar program; but i don't know how to enable High protection mode with pass via c#.

    if i use CRYPT_USER_PROTECTED my program show the dialog, in this dialog i select high protection and i digit the password.

    do you have me some hints for me?

    thanks

    LuX

  • There is any way to import a certificate revocation list without user interaction? do you have any example?

  • Thanks, that's exactly what I was looking for.

  • Hi, alejacma

    Do you have any ideas/examples on how to P/Invoke the CryptUIWizExport function from the Cryptui.dll within C# whilst passing a .NET X509Certificate as a parameter?

    Many thanks!

    Matt

  • I don't have a sample, but it shouldn't be too difficult to achieve. You can use the Handle property of the X509Certificate2 object to create a CERT_CONTEXT struct (see blogs.msdn.com/.../how-to-call-cryptmsg-api-in-streaming-mode-c.aspx for a sample on how to do that), and then you can pass a pointer to that context to the API.

    If you have a Premier contract you may open an Advisory case and I could assist you on that.

  • Hi,

    Anyone have this example compiled?

    Thanks

  • Hi,

    Anyone have this example compiled?

  • Hi

    I need to use this program as a windows service that it runs periodic. every thing is ok, but I dont know what must i do to warning  message that Asif Alam pointed.

    I'll appreciate if you can guide me to solve this

Page 1 of 2 (16 items) 12
Leave a Comment
  • Please add 2 and 7 and type the answer here:
  • Post
Translate This Page