.NET 相互 SSL 握手“客户端身份验证”

D f*_*per 5 .net c# apache authentication ssl

过去几天我一直在解决这个问题,但一无所获。

场景是:

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

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

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

我用来使用 SslStream 执行身份验证的示例代码。使用这种方法我得到一个错误说明

The message received was unexpected or badly formatted

管理 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我用来使用 HttpWebRequest 执行身份验证的示例代码。使用这种方法给了我以下问题

The request was aborted: Could not create SSL/TLS secure channel.

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;
Run Code Online (Sandbox Code Playgroud)

我希望这是有道理的。我只想知道我所做的一切是对还是错。

pep*_*epo 5

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

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

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