Automate SSL certificate install to IIS 6 sites using C#
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...
- Add reference to COM component IIS CertObj 1.0 Type Library
- On the added reference CERTOBJLib, in the properties sheet, set 'Embed Interop Types' to false
- 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.
精彩评论