Freigeben über


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

Hi, welcome back,

Today I'm posting a CryptoAPI sample which usesCryptUIWizImport 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)

Comments

  • Anonymous
    February 18, 2008
    The comment has been removed
  • Anonymous
    February 18, 2008
    The comment has been removed
  • Anonymous
    February 19, 2008
    The comment has been removed
  • Anonymous
    February 19, 2008
    The comment has been removed
  • Anonymous
    July 25, 2008
    The comment has been removed
  • Anonymous
    August 25, 2008
    The comment has been removed
  • Anonymous
    September 11, 2008
    This is exactly what I am looking for, however, I need to code it using VBA.  Is this possible?
  • Anonymous
    October 05, 2008
    The comment has been removed
  • Anonymous
    April 20, 2009
    There is any way to import a certificate revocation list without user interaction? do you have any example?
  • Anonymous
    May 27, 2009
    Thanks, that's exactly what I was looking for.
  • Anonymous
    July 11, 2010
    Hi, alejacmaDo 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
  • Anonymous
    July 11, 2010
    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.
  • Anonymous
    June 15, 2011
    Hi,Anyone have this example compiled?Thanks
  • Anonymous
    June 15, 2011
    Hi,Anyone have this example compiled?
  • Anonymous
    May 26, 2012
    HiI 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
  • Anonymous
    May 27, 2012
    Hi Mariam,I haven't "played" with this on Windows services, and I didn't have time to investage about the warning dialog that Asif pointed out, if it is mandatory or if it can be dismissed in any way. If you need urgent help, I suggest you open a Technical Support case with us so we can assist you.Regards,Alex
  • Anonymous
    July 12, 2012
    I have this code and it works fine but I created the request with certreq and it created a private key file that I don't know the name of so when I import the certificate it doesn't have a private key associated with it.  Does anybody know how to create the private key file with a specific name when user certreq?  I've looked at all of the parameters that go in the .INF file but could not find anything that would allow me to control the name of the private key.