我目前正在构建一个ASP.Net MVC 3 eccomerce应用程序,该应用程序使用IIS Express作为我的开发服务器。
由于我们通过应用程序接受付款,我们需要在结账过程中强制使用SSL连接。
在阅读了Scott Hanselman写的关于如何设置用于IIS Express的自签名SSL证书的文章之后,我可以通过以下两种方式访问我的网站:
- http://localhost
- https://localhost
这都是肉汁,直到我重新开始。似乎每次重新启动(无论出于何种原因)时,我都需要再次运行以下命令:
netsh http delete sslcert ipport=0.0.0.0:443
netsh http add sslcert ipport=0.0.0.0:443 appid={214124cd-d05b-4309-9af9-9caa44b2b74a} certhash=<thumbprint from Certificate Manager>
我已尝试导出和导入生成的证书,并将证书从个人存储拖动到受信任的根证书颁发机构。两者都无济于事。
有人有什么想法吗?
在http://www.hanselman.com/blog/WorkingWithSSLAtDevelopmentTimeIsEasierWithIISExpress.aspx
最后的评论是:
我认为,将自签名证书从Personal移到Trusted Root CA目录会导致SSL在开发人员重新启动机器后停止工作的问题。(不知道它是如何发生的,但它确实会持续发生。)我最终通过导出并将自签名证书重新导入到受信任的根目录(而不是简单地将其拖过去)来解决这个问题。现在,我的自签名证书已被考虑在内,我不需要每次重新启动计算机时都重新安装/修复IIS Express。
是否将证书导入到当前用户或LocalMachine存储?看起来,如果您将证书导入CurrentUser存储,就会出现此问题。看看下面的线索http://social.msdn.microsoft.com/Forums/en/wcf/thread/9e560c64-c53a-4de5-80d5-d2231ba8bcb1
一些评论。
首先,您可以使用以下命令在不使用MMC的情况下访问IIS Express指纹:
powershell-command"&{getchilditem-path cert:\localmachine\my|where object{$.FriendlyName-match‘IIS Express Development Certificate’}|%{$.Tumbprint}}"
如中所述http://msdn.microsoft.com/en-us/library/ms733791.aspx,在netsh的命令中使用指纹。您可以使用上面的powershell技术为IIS Express的特定安装构造正确的netsh命令。
让我们添加到上面的命令中,并让它为端口443输出正确的netsh命令:
powershell-command"&{get-chchilditem-path cert:\localmachine\my| where object{$.FriendlyName-match'IIS Express Development Certificate'}|%{'netsh http add sslcert-ipport=0.0.0.0:443 appid={214124cd-d05b-4309-9af9-9caa44b2bb74a}certhash='+$.Thumbprint}"
这将显示您应该使用的完整netsh命令。您可以复制/粘贴它并自己调用它。您也可以在上面的命令中添加**|cmd.exe**以自动调用它。让我们这样做吧。下面是上面的PowerShell命令,您可以将其复制/粘贴到管理命令提示符中,以设置将本地443端口绑定到本地IIS Express证书:
powershell-command"&{get-chchilditem-path cert:\localmachine\my | where object{$.FriendlyName-match'IIS Express Development Certificate'}|%{'netsh http add sslcert ipport=0.0.0.0:443 appid={214124cd-d05b-4309-9af9-9caa44b2bb74a}certhash='+$.Tumbprint}}"|cmd.exe
下面是一个PowerShell脚本,可以删除现有证书,然后创建一个新的自签名证书并将其绑定到IIS 8.0 Express。要运行它而启动的PowerShell必须使用"以管理员身份运行"。我使用它将密钥大小从默认的1024位增加到4096位。
# NOTE: This script MUST use Run as Administrator to work correctly.
# This script works with IIS 8.0 Express.
$currentIdentity=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$currentPrincipal=new-object System.Security.Principal.WindowsPrincipal($currentIdentity)
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator
if (($currentPrincipal -eq $null) -or ($currentPrincipal.IsInRole($adminRole) -eq $false))
{
Write-Error "This script must be run with Admnistrator privileges."
exit
}
$iisExpressAppId = "{214124cd-d05b-4309-9af9-9caa44b2b74a}"
$iisExpressCertFriendlyName = "IIS Express Development Certificate"
# Get the current IIS Express certificate and remove it if it exists
$iisExpressCert = Get-ChildItem Cert:LocalMachineMy | ? { $_.FriendlyName -eq $iisExpressCertFriendlyName }
if ($iisExpressCert -ne $null)
{
Remove-Item $iisExpressCert.PSPath
}
# Create a new self-signed server certificate with a 4096-bit key
& "C:Program Files (x86)Windows Kits8.1binx86makecert.exe" -r -pe -n "CN=localhost" -m 60 -ss My -sr LocalMachine -sky Exchange -eku 1.3.6.1.5.5.7.3.1 -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 -a sha512 -len 4096
# Get the newly generated server certificate
$iisExpressCert = Get-ChildItem Cert:LocalMachineMy | ? { $_.Subject -eq "CN=localhost" -and [DateTime]::Parse($_.GetEffectiveDateString()).Date -eq [DateTime]::Today }
if ($iisExpressCert -ne $null)
{
# Change the friendly name of the new certificate.
$iisExpressCert.FriendlyName = $iisExpressCertFriendlyName
# Iterate through the IIS Express ports removing the old certificate
# and adding the new one.
44300..44399 | foreach {
& "C:WindowsSystem32netsh.exe" http delete sslcert ipport=0.0.0.0:$($_)
& "C:WindowsSystem32netsh.exe" http add sslcert ipport=0.0.0.0:$($_) certhash=$($iisExpressCert.Thumbprint) appid=$($iisExpressAppId)
}
}
<# Remove comment tags only if you intend to trust the self-signed cert.
# Adds the Public Certificate to the Trusted Root Certification Authorities.
$iisExpressPublicCert = Get-ChildItem Cert:LocalMachineAuthRoot | ? { $_.FriendlyName -eq $iisExpressCertFriendlyName }
if ($iisExpressPublicCert -ne $null)
{
Remove-Item $iisExpressPublicCert.PSPath
}
$iisExpressPublicCert = New-Object "System.Security.Cryptography.X509Certificates.X509Certificate2" @(,$iisExpressCert.Export("Cert"))
$iisExpressPublicCert.FriendlyName = $iisExpressCertFriendlyName
$trustedCertStore = Get-Item Cert:LocalMachineAuthRoot
$trustedCertStore.Open("ReadWrite")
$trustedCertStore.Add($iisExpressPublicCert)
$trustedCertStore.Close()
#>