【发布时间】:2017-10-08 23:44:52
【问题描述】:
我已经使用自签名证书设置了一个测试 C# Https Listener(遵循 Httplistener with https support 中的建议)。
该服务(在本地系统下作为 Windows 服务运行)和最初(启动后)运行良好。 在一段时间(约 1.5 小时)后,对 https 端点的调用停止使用 Edge/IE 抱怨:
无法安全连接到此页面 这可能是因为该站点使用过时或不安全的 TLS 安全设置。如果这种情况持续发生,请尝试联系网站所有者。
Chrome 报错如下:
无法访问此网站 连接被重置。 ERR_CONNECTION_RESET
发生这种情况时,检查证书存储会显示证书(在 Root 和 My 存储中)仍然存在。
检查
netsh http 显示 sslcert
也说明注册到端口的证书还在。
重新启动应用程序(重新创建、重新安装和重新绑定证书到 C# http(s) 侦听器侦听的端口)会有所帮助,但直到下一个可能在一段时间内发生的故障(~1.5. .2 小时?)。
我知道侦听器线程仍然存在,因为不安全端口上的请求仍然有效。
在此期间发生了一些事情,我不知道是什么......
代码:
一切从生成自签名证书开始:
// create DN for subject and issuer
var dn = new CX500DistinguishedName();
dn.Encode("CN=localhost");
// create a new private key for the certificate
var privateKey = new CX509PrivateKey
{
ProviderName = "Microsoft Base Cryptographic Provider v1.0",
MachineContext = false,
Length = 2048,
KeySpec = X509KeySpec.XCN_AT_SIGNATURE,
KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_SIGNING_FLAG,
FriendlyName = "Application Testing Key",
ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG
};
privateKey.Create();
var hashobj = new CObjectId();
hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID,
ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY,
AlgorithmFlags.AlgorithmFlagsNone, "SHA256");
// Create the self signing request
var certificateRequest = new CX509CertificateRequestCertificate();
certificateRequest.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser, privateKey, String.Empty);
certificateRequest.Subject = dn;
certificateRequest.Issuer = dn; // the issuer and the subject are the same
certificateRequest.NotBefore = DateTime.UtcNow.AddDays(-1);
certificateRequest.NotAfter = DateTime.UtcNow.AddYears(10);
certificateRequest.HashAlgorithm = hashobj;
// Set up the Subject Alternative Names extension.
var nameslist = new CAlternativeNames();
var alternativeName = new CAlternativeName();
alternativeName.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, "localhost");
nameslist.Add(alternativeName);
var subjectAlternativeNamesExtension = new CX509ExtensionAlternativeNames();
subjectAlternativeNamesExtension.InitializeEncode(nameslist);
certificateRequest.X509Extensions.Add((CX509Extension)subjectAlternativeNamesExtension);
var skiExtension = new CX509ExtensionSubjectKeyIdentifier();
skiExtension.InitializeEncode(EncodingType.XCN_CRYPT_STRING_BASE64, Convert.ToBase64String(StringToByteArray(certSKI)));
certificateRequest.X509Extensions.Add((CX509Extension)skiExtension);
certificateRequest.Encode();
// Do the final enrollment process
var enroll = new CX509Enrollment();
enroll.InitializeFromRequest(certificateRequest); // load the certificate
enroll.CertificateFriendlyName = "Application Testing Cert";
var csr = enroll.CreateRequest(); // Output the request in base64
var pwd = Guid.NewGuid().ToString();
enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, csr, EncodingType.XCN_CRYPT_STRING_BASE64, pwd); // and install it back as the response
var base64encoded = enroll.CreatePFX(pwd, PFXExportOptions.PFXExportChainWithRoot);
// instantiate the target class with the PKCS#12 data
return new X509Certificate2(Convert.FromBase64String(base64encoded), pwd);
随后将新生成的证书添加到 localhost 根和私有存储:
InstallCertificateToCertStore(cert, new X509Store(StoreName.Root, StoreLocation.LocalMachine));
InstallCertificateToCertStore(cert, new X509Store(StoreName.My, StoreLocation.LocalMachine));
随后将新创建并安装的证书注册到 Http Listener 侦听的端口:
netsh.exe http add sslcert ipport=0.0.0.0:{port} certhash={certThumbprint} appid={appid_guid}
【问题讨论】:
-
经过进一步的广泛搜索后,似乎原因可能是我没有保留私钥:support.microsoft.com/en-us/help/950090/… 现在测试。
标签: c# ssl self-signed httplistener netsh