Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

automate installation of p12 certificate file

Tags:

c#

My target is to automate a certificate installation without any user interaction at all.

requirements:

  • install for current user
  • enable strong private key protection
  • mark this key as exportable
  • set private key security level to high (request my permission with a password when this item is to be used)

code:

using System.Security.Cryptography.X509Certificates;
X509Certificate2 cert = new X509Certificate2(
     "file.p12", "password", 
      X509KeyStorageFlags.UserProtected
     | X509KeyStorageFlags.UserKeySet
     | X509KeyStorageFlags.Exportable);
X509Store store = new X509Store(StoreName.My);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);

the above code installs the certificate for the current user under the personal store and is able to manage the first gui: Screenshot - Certificate Import Wizard

but it is not able to set the security level, instead a gui is opened: Screenshot2

Edit:

there is actually a other method available via UWP called "UserCertificateEnrollmentManager.ImportPfxDataAsync Method" Link. the "KeyProtectionLevel Enum" gives you here the "ConsentWithPassword" option, but UWP is totally new for me and i would prefer to stick to the console .net

like image 254
Dave Avatar asked Dec 11 '25 02:12

Dave


1 Answers

Testing with UWP shows an additional 'UWP style' dialog requesting consent for the cert operation and then asks for a password to be created so it does skip over the GUI shown in your Screenshot2. I don't know if that's helpful?

UWP consent dialog

Windows security cert pass dialog

private async Task<string> PickPfx()
{
    var openPicker = new FileOpenPicker()
    {
        ViewMode = PickerViewMode.List,
        SuggestedStartLocation = PickerLocationId.Desktop,
    };

    openPicker.FileTypeFilter.Add(".pfx");
    openPicker.FileTypeFilter.Add(".p12");

    var file = await openPicker.PickSingleFileAsync();
    if (file == null)
        return null;

    int length = (int)(await file.GetBasicPropertiesAsync()).Size;
    byte[] bytes = new byte[length];

    using (var stream = await file.OpenStreamForReadAsync())
    {
        await stream.ReadAsync(bytes, 0, length);
    }

    return Convert.ToBase64String(bytes);
}

private async void InstallCert_Click(object sender, RoutedEventArgs e)
{
    const string CERT_PASS = "123test";

    string pfx64 = await PickPfx();
    if (pfx64 == null)
        return;

    var importParams = new PfxImportParameters()
    {
        Exportable = ExportOption.Exportable,
        FriendlyName = "My test cert",
        KeyProtectionLevel = KeyProtectionLevel.ConsentWithPassword,
    };

    var ucem = CertificateEnrollmentManager.UserCertificateEnrollmentManager;
    await ucem.ImportPfxDataAsync(pfx64, CERT_PASS, importParams);
}
like image 57
joehoper Avatar answered Dec 13 '25 16:12

joehoper