开发者

Automate SSL certificate install to IIS 6 sites using C#

开发者 https://www.devze.com 2023-04-13 08:57 出处:网络
I\'m trying to automate the process of generating a site in IIS 6 via C# code.I\'m using DirectoryServices and I\'m nearly there..I have it creating the site, setting up all the bindings etc. just fin

I'm trying to automate the process of generating a site in IIS 6 via C# code. I'm using DirectoryServices and I'm nearly there.. I have it creating the site, setting up all the bindings etc. just fine. I have not figured out how to install our wildcard ssl cert. Here's the details:

We have a SSL certificate that matches '*.example.com'. Every site we host has a server binding that matches. e.g开发者_JAVA百科. 'test.example.com'. I think I know how to add the SecureBinding property:

DirectoryEntrySite.Properties["SecureBindings"][0] = "xx.xx.xx.xx:443:test.example.com";

But I have had no success finding information on how to automatically install the certificate to the site. In the IIS 6 Manager, you would do this by right clicking a site -> properties -> Directory Security -> Server Certificate -> Next -> Assign an existing certificate -> (select certificate) -> Next...

Can anyone help?


See this: http://forums.iis.net/t/1163325.aspx

using Microsoft.Web.Administration;  

X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite);

X509Certificate2 certificate = new X509Certificate2(pfxFilePath);

store.Add(certificate);

using (ServerManager serverManager = new ServerManager())
{
    Site site = serverManager.Sites["Default Web Site"];

    if (site != null)
    {
         site.Bindings.Add("*:443:", certificate.GetCertHash(), store.Name);
    }

    store.Close();
}


OK, this question is already answered, but the awarded answer is not for IIS6, but rather IIS7 and greater. The namespace Microsoft.Web.Administration is not available for IIS6. We hobbled together a series of technologies, all in .NET 4.0 to make this work.

Steps...

  1. Add reference to COM component IIS CertObj 1.0 Type Library
  2. On the added reference CERTOBJLib, in the properties sheet, set 'Embed Interop Types' to false
  3. Create a class with the following method...

using System.Linq;
using System.Management;
namespace CertStuff
{
    public class CertificateInstaller
    {
public void RegisterCertificateWithIIS6(string webSiteName, string certificateFilePath, string certificatePassword)
        {
            // USE WMI TO DERIVE THE INSTANCE NAME
            ManagementScope managementScope = new ManagementScope(@"\\.\root\MicrosoftIISv2");
            managementScope.Connect();
            ObjectQuery queryObject = new ObjectQuery("SELECT Name FROM IISWebServerSetting WHERE ServerComment = '" + webSiteName + "'");
            ManagementObjectSearcher searchObject = new ManagementObjectSearcher(managementScope, queryObject);
            var instanceNameCollection = searchObject.Get();
            var instanceName = (from i in instanceNameCollection.Cast<ManagementObject>() select i).FirstOrDefault();

            // USE IIS CERT OBJ TO IMPORT CERT - THIS IS A COM OBJECT
            var IISCertObj = new CERTOBJLib.IISCertObjClass();
            IISCertObj.InstanceName = instanceName["Name"].ToString();
            IISCertObj.Import(certificateFilePath, certificatePassword, false, true); // OVERWRITE EXISTING
        }

    }
}

to remove the cert reference, use the following method...

public void UnRegisterCertificateWithIIS6(string webSiteName)
        {
            // USE WMI TO DERIVE THE INSTANCE NAME
            ManagementScope managementScope = new ManagementScope(@"\\.\root\MicrosoftIISv2");
            managementScope.Connect();
            ObjectQuery queryObject = new ObjectQuery("SELECT Name FROM IISWebServerSetting WHERE ServerComment = '" + webSiteName + "'");
            ManagementObjectSearcher searchObject = new ManagementObjectSearcher(managementScope, queryObject);

            foreach (var instanceName in searchObject.Get())
            {
                var IISCertObj = new CERTOBJLib.IISCertObjClass();
                IISCertObj.InstanceName = instanceName["Name"].ToString();

                // THE REMOVE CERT CALL COMPLETES SUCCESSFULLY, BUT FOR WHATEVER REASON, IT ERRORS OUT.
                // SWALLOW THE ERROR.
                try
                {
                    IISCertObj.RemoveCert(false, true);
                }
                catch (Exception ex)
                {

                }
            }
        }

NOTE: if you receive error "Interop type 'CERTOBJLib.IISCertObjClass' cannot be embedded. Use the applicable interface instead.", this means step 2 was skipped. Ensure the reference object is NOT embedded.


To do this with .Net 4.7 and IIS 10, you can pass the following flags:

X509Certificate2 certificate = new X509Certificate2(path, "password", X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable| X509KeyStorageFlags.MachineKeySet);

If you are storing the cert in the CurrentUser store rather than in the LocalMachine store, do the following:

X509Certificate2 certificate = new X509Certificate2(path, "password", X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable| X509KeyStorageFlags.UserKeySet);

The Key set flags indicate the following:

//
// Summary:
//     Private keys are stored in the current user store rather than the local computer
//     store. This occurs even if the certificate specifies that the keys should go
//     in the local computer store.
UserKeySet = 1,
//
// Summary:
//     Private keys are stored in the local computer store rather than the current user
//     store.
MachineKeySet = 2,

The private key needs to be in the same place as the rest of the certificate for it to work with IIS.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号