.NET Mutual SSL握手'客户端身份验证'

时间:2014-03-10 22:57:33

标签: c# .net apache ssl authentication

我正在解决这个问题,最近几天我无法到达任何地方。

情景是 该领域的iOS应用程序将调用我的REST服务(.NET)。 我的REST服务将使用Mutual SSL握手调用Apache Web服务。 无论我收到什么数据,我都必须将该数据传回现场的iOS设备。

唯一的问题是My REST Service和Apache Web服务之间的第二部分通信。

客户端证书已使用客户端身份验证,数字证书,密钥加密的关键用法进行签名。我的证书的根歌手已经放在Apache服务器上。如果我们尝试使用Web浏览器,我们可以毫无问题地执行握手。

我用于使用SslStream执行身份验证的示例代码。使用此方法,我收到一条错误消息,指出“ 收到的消息是意外的或格式错误的 ”,管理Apache Web服务器的人说他们可以看到请求进来但据他们说,他们没有收到并证明这一点。

var certificate = @“certificate.cer”;
var hostAddress = “hostAddress";
var certificates = new X509Certificate2Collection(new X509Certificate2(certificate));
RunClient(hostAddress, 1316, certificates);

static void RunClient(string hostName, int port, X509Certificate2Collection certificates)
{
            TcpClient client = new TcpClient(hostName, port);
            SslStream sslStream = new SslStream(client.GetStream(), false, ValidateServerCertificate);
            try
            {
                sslStream.AuthenticateAsClient(hostName, certificates, SslProtocols.Ssl3, true);
                Write("authenticated.");
            }
            catch (AuthenticationException ex)
            {
                Write("Inner: " + ex.InnerException.Message);                
            }
            catch (Exception ex)
            {
                Write(ex.Message);
            }
}

我用于使用HttpWebRequest执行身份验证的示例代码。使用此方法会出现以下问题“ 请求已中止:无法创建SSL / TLS安全通道。

var certificate = @“certificate.cer”;
var hostAddress = “hostAddress";
var certificates = new X509Certificate2Collection(new X509Certificate2(certificate));
public static T Post(string url, string body, X509Certificate2 cert)
        {
            var webRequest = FBJsonRequestService.CreateRequest(url, cert, WebRequestMethods.Http.Post, body);
            using (var webResponse = webRequest.GetResponse())
            {
                return CreateResponse(webResponse);
            }
        }
var webRequest = (HttpWebRequest) WebRequest.Create(url);
            webRequest.ClientCertificates.Add(cert);
            //webRequest.AuthenticationLevel = AuthenticationLevel.MutualAuthRequested;
            webRequest.Credentials = CredentialCache.DefaultNetworkCredentials;
            webRequest.Method = method;
            webRequest.ContentType = "application/json; charset=utf-8";
            if (body != null)
            {
                using (var streamWriter = new StreamWriter(webRequest.GetRequestStream()))
                {
                    streamWriter.Write(body);
                }
            }
            return webRequest;

希望这是有道理的,如果我正在做的事情是正确的,或者我做错了,我想知道。

3 个答案:

答案 0 :(得分:3)

我认为文件 certificate.cer 的内容不正确。我认为扩展.cer只包含证书,但不包含私钥。

您必须使用包含私钥的 certificate.p12 certificate.pfx 。这些扩展代表PKCS#12标准。这些文件中还可以包含整个证书链。

您可以使用 X509Certificate2 类的不同构造函数加载p12文件。请查看this documentation

答案 1 :(得分:0)

感谢Pepo,

我认为我使用了错误的文件。我不得不使用PFX文件而不是CER。我的问题完全是另一回事。这是证书本身的一些安全限制。在发布之前,我甚至不确定我是否做得对。

我为以后需要帮助的人创建了以下blog

答案 2 :(得分:0)

异常的另一个原因“请求已中止:无法创建SSL / TLS安全通道” 是服务器可能不支持安全协议类型。

另一种协议类型是TLS,它比SSL3更安全, 以下代码可以帮助您

 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;