在当今的网络世界中,数据安全至关重要。HTTPS和SSL(安全套接层)协议为提供了一种安全的方式来传输数据。然而,仅仅使用这些技术并不能保证安全。本文将探讨如何通过自定义证书策略和验证服务器证书来增强Web服务的安全性。
大多数Web服务都部署在HTTPS上,并通过SSL进行加密,以防止未授权的使用。当浏览HTTPS网站时,通常会弹出一个证书对话框,要求信任提供者。这是由Web服务器发送的服务器证书。接受证书并继续前进。在桌面应用程序中,当执行类似的任务,比如访问使用HTTPS和SSL的Web服务时,无法接收任何对话框来信任证书,这就出现了问题。
要解决这个问题,可以创建一个实现ICertificatePolicy接口的自定义CertificatePolicy类。例如,可以这样编写此类:
public class MyPolicy : ICertificatePolicy {
public MyPolicy() {
}
public bool CheckValidationResult(ServicePoint srvPoint,
X509Certificate certificate,
WebRequest request,
int certificateProblem)
{
// 执行操作以验证证书并返回true或false
return true;
}
}
然后可以设置:
ServerCertificateValidationCallback = new MyPolicy();
上述代码使用委托System.Net.ServicePointManager.ServerCertificateValidationCallback来接受服务器证书。它隐式返回true,这意味着它接受任何服务器证书并继续访问Web服务。
SSL主要用于安全性和加密,如果这么容易被绕过,那么SSL的意义何在?当客户端验证服务器证书与任何证书文件时,即不验证验证证书以验证服务器证书,客户端将无法访问任何Web服务。这就像提供密码或认证密码。如果没有实际认证,一个提供和接收数据的Web服务应该很容易被伪造。因此,需要使用“正确”版本的验证证书来验证服务器证书。验证证书只是一个CA文件,它比较服务器证书的数据。如果两者匹配,它返回true并允许访问Web服务,否则返回false并不允许访问Web服务及其机密数据。
这里是一段代码,可以帮助接受服务器证书并验证证书是否与CA文件匹配。
private X509Certificate2 verifyCert = null;
private void setSSLCertificate() {
veriftCert = new X509Certificate2("ca_verify.crt");
ServicePointManager.ServerCertificateValidationCallback +=
new System.Net.Security.RemoteCertificateValidationCallback(customCertificateValidation);
}
public bool customCertificateValidation(Object sender,
X509Certificate certificate, X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
// 这里接受了服务器证书
// 现在,验证证书是否与verifyCert匹配
// 如果两个证书的详细信息匹配,则返回true,否则返回false
return verifyCert.Verify();
}
这样,就处理了Peer Verification,并且不应该在代码中进行硬编码或比较。
现在,每当执行任何请求时,首先会调用customCertificateValidation(),如果它返回true,则请求将能够继续,否则会捕获WebException。
private void SendPost(String post_data) {
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://ae-q01.com/");
request.KeepAlive = true;
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
byte[] postBytes = Encoding.ASCII.GetBytes(post_data);
Stream requestStream = null;
try {
request.ContentLength = postBytes.Length;
requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
} catch (WebException we) {
// 如果customCertificateValidation返回false,这里会捕获
// 可以检查WebException we.Status的状态,
// 大多数情况下它会返回TrustFailure并处理它们
} catch (Exception e) {
// 处理其他正常的请求错误
} finally {
if (requestStream != null)
requestStream.Close();
}
}
不要忘记在应用程序开始时或在调用任何Web服务之前适当的时候调用setSSLCertificate()。
这就是SSL Peer Verification的处理方式。相信这肯定会帮助更多实际交叉检查SSL验证而不是盲目接受服务器证书的开发者。