关于证书的困惑
端口
我有由 IIS 托管的 WCF REST Web 服务,它在 HTTPS 上运行,我在 IIS 上生成证书并将 https 分配给我通过 IE 浏览器生成 cer 的 。我创建一个测试应用程序,无论是否添加客户端证书,甚至添加错误的证书,都会发生连接,并且我会得到正确的响应。我想知道如果没有发送证书,消息是如何解密的。
要么目的地不安全,要么我误解了整件事。 另外,
我从回调“CheckValidationResult()”中得到的错误是 证书CN_NO_MATCH = 0x800B010F 或者 “未知证书问题”,在这种情况下,certificateProblem(CheckValidationResult 的参数)为 0
什么是 CertCN_NO_MATCH 错误,什么是 CN?
请参阅下面的代码。
ServicePointManager.CertificatePolicy = new CertPolicy();
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(String.Format("https://{0}/uri", ip));
//request.ClientCertificates.Add(new X509Certificate("D:\\ThePubKey.cer"));
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
using (StreamWriter stream = new StreamWriter(request.GetRequestStream()))
{
stream.Write("RequestType=CheckStatus&ReportType=Fulfillment&ReportID=5");
}
using (StreamReader stream = new StreamReader(request.GetResponse().GetResponseStream()))
{
Response.ContentType = "text/xml";
Response.Output.Write(stream.ReadToEnd());
Response.End();
}
class CertPolicy : ICertificatePolicy
{
public enum CertificateProblem : uint
{
CertEXPIRED = 0x800B0101,
CertVALIDITYPERIODNESTING = 0x800B0102,
CertROLE = 0x800B0103,
CertPATHLENCONST = 0x800B0104,
CertCRITICAL = 0x800B0105,
CertPURPOSE = 0x800B0106,
CertISSUERCHAINING = 0x800B0107,
CertMALFORMED = 0x800B0108,
CertUNTRUSTEDROOT = 0x800B0109,
CertCHAINING = 0x800B010A,
CertREVOKED = 0x800B010C,
CertUNTRUSTEDTESTROOT = 0x800B010D,
CertREVOCATION_FAILURE = 0x800B010E,
CertCN_NO_MATCH = 0x800B010F,
CertWRONG_USAGE = 0x800B0110,
CertUNTRUSTEDCA = 0x800B0112
}
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
{
// You can do your own certificate checking.
// You can obtain the error values from WinError.h.
// Return true so that any certificate will work with this sample.
String error = "";
using (StringWriter writer = new StringWriter())
{
writer.WriteLine("Certificate Problem with accessing " + request.RequestUri);
writer.Write("Problem code 0x{0:X8},", (int)certificateProblem);
writer.WriteLine(GetProblemMessage((CertificateProblem)certificateProblem));
error = writer.ToString();
}
return true;
}
private String GetProblemMessage(CertificateProblem Problem)
{
String ProblemMessage = "";
CertificateProblem problemList = new CertificateProblem();
String ProblemCodeName = Enum.GetName(problemList.GetType(), Problem);
if (ProblemCodeName != null)
ProblemMessage = ProblemMessage + "-Certificateproblem:" +
ProblemCodeName;
else
ProblemMessage = "Unknown Certificate Problem";
return ProblemMessage;
}
}
I have WCF REST web service hosted by IIS, it works on HTTPS, I generate Certificate on IIS and assign Https to a port
I generate cer through IE browser. I create a test application and regardless Add a client certificate or not or even add a wrong certificate the connection take place and a I get correct response. I am wondering how the message was decrypted if there is no certificate sent.
Either the destination is not secured or I misunderstand the whole thing.
also
The error I have from the callback "CheckValidationResult()" is either
CertCN_NO_MATCH = 0x800B010F
or
"Unknown Certificate Problem" , the certificateProblem (parameter of CheckValidationResult) is 0 for this case
What is CertCN_NO_MATCH eror, what is CN?
See code below.
ServicePointManager.CertificatePolicy = new CertPolicy();
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(String.Format("https://{0}/uri", ip));
//request.ClientCertificates.Add(new X509Certificate("D:\\ThePubKey.cer"));
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
using (StreamWriter stream = new StreamWriter(request.GetRequestStream()))
{
stream.Write("RequestType=CheckStatus&ReportType=Fulfillment&ReportID=5");
}
using (StreamReader stream = new StreamReader(request.GetResponse().GetResponseStream()))
{
Response.ContentType = "text/xml";
Response.Output.Write(stream.ReadToEnd());
Response.End();
}
class CertPolicy : ICertificatePolicy
{
public enum CertificateProblem : uint
{
CertEXPIRED = 0x800B0101,
CertVALIDITYPERIODNESTING = 0x800B0102,
CertROLE = 0x800B0103,
CertPATHLENCONST = 0x800B0104,
CertCRITICAL = 0x800B0105,
CertPURPOSE = 0x800B0106,
CertISSUERCHAINING = 0x800B0107,
CertMALFORMED = 0x800B0108,
CertUNTRUSTEDROOT = 0x800B0109,
CertCHAINING = 0x800B010A,
CertREVOKED = 0x800B010C,
CertUNTRUSTEDTESTROOT = 0x800B010D,
CertREVOCATION_FAILURE = 0x800B010E,
CertCN_NO_MATCH = 0x800B010F,
CertWRONG_USAGE = 0x800B0110,
CertUNTRUSTEDCA = 0x800B0112
}
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
{
// You can do your own certificate checking.
// You can obtain the error values from WinError.h.
// Return true so that any certificate will work with this sample.
String error = "";
using (StringWriter writer = new StringWriter())
{
writer.WriteLine("Certificate Problem with accessing " + request.RequestUri);
writer.Write("Problem code 0x{0:X8},", (int)certificateProblem);
writer.WriteLine(GetProblemMessage((CertificateProblem)certificateProblem));
error = writer.ToString();
}
return true;
}
private String GetProblemMessage(CertificateProblem Problem)
{
String ProblemMessage = "";
CertificateProblem problemList = new CertificateProblem();
String ProblemCodeName = Enum.GetName(problemList.GetType(), Problem);
if (ProblemCodeName != null)
ProblemMessage = ProblemMessage + "-Certificateproblem:" +
ProblemCodeName;
else
ProblemMessage = "Unknown Certificate Problem";
return ProblemMessage;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我刚刚回复了这个类似的问题(在 Java 中)。
CN 是“通用名称”。它应该是您要连接的服务器的主机名(除非它位于主题备用名称中)。我从你的代码示例中猜想你直接使用IP地址。在这种情况下,CN 应该是该 IP 地址(使用主机名而不是 IP 地址往往更好)。有关规范,请参阅 RFC 2818(第 3.1 节)。
请注意,CN 或主题备用名称是从客户端的角度来看的,因此如果您连接到 https:// some.example.com/,那么证书中的名称应该是 some.example.com,如果连接到 https://localhost/,那么证书中的名称应该是 localhost,即使是 some. example.com 和 localhost 实际上可能是同一台服务器。
(我猜想默认情况下,IIS 可能会为外部名称生成一个证书,但您必须查看该证书才能知道;这应该在证书属性中的某个位置可见。)
I've just replied to this similar question (in Java).
CN is the "Common Name". It ought to be the hostname of the server to which you're connecting (unless it's in the subject alternative name). I guess from your code sample that you're using the IP address directly. In this case, the CN should be that IP address (it tends to be better to use a hostname rather than an IP address). See RFC 2818 (sec 3.1) for the specifications.
Note that the CN or subject alternative name is from the point of view of the client, so if you connect to https://some.example.com/, then the name in the cert should be some.example.com, if you connect to https://localhost/, then the name in the cert should be localhost, even if some.example.com and localhost may be the same server effectively.
(I guess that by default, IIS might generate a certificate for the external name, but you'd have to look at the certificate to know; this should be visible in the certificate properties somewhere.)