首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DotNet核心:如何跨平台客户端证书TLS认证?

DotNet核心:如何跨平台客户端证书TLS认证?
EN

Stack Overflow用户
提问于 2019-05-09 12:24:15
回答 1查看 828关注 0票数 1

我正试图开发一个跨平台应用程序(windows/mac os x),它需要使用ClientCertificate身份验证在服务器上签名XML文件并发出web请求.

主要的限制是我需要在智能卡上使用证书.

目前我正在使用DotNetCore2.1。

首先,我确实尝试使用dotnet核心X509Store,但是在MacOs上,我无论如何都不能访问PrivateKey对象( XML是强制性的),然后我放弃了这个引线。

然后,我在特定于厂商的dll中使用pkcs11interop来访问智能卡,它在XML签名中运行良好(我在pkcs11interop对象中包装了pkcs11interop调用,然后在SignedXml中使用该对象作为SigningKey ),但它不适用于ClientCertificate连接。

通常,我使用此方法连接到服务器(DotNetFramework4.6.1,仅限windows ):

代码语言:javascript
复制
HttpWebRequest req = WebRequest.Create("https://sometlsserver.com/") as HttpWebRequest;
req.ClientCertificates.Add(cert);
HttpWebResponse res = req.GetResponse() as HttpWebResponse;
using (StreamReader sr = new StreamReader(res.GetResponseStream(), new UTF8Encoding(false)))
{
    return sr.ReadToEnd();
}

并生成证书:

代码语言:javascript
复制
var certAttr = session.GetAttributeValue(handle, new List<CKA>
{
    CKA.CKA_VALUE,
};
var cert = new X509Certificate2(certAttr[0].GetValueAsByteArray());

当我试图连接到我的经典方法时,我有几个例外:

代码语言:javascript
复制
System.Net.WebException: The SSL connection could not be established, see inner exception. Authentication failed, see inner exception.
---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> System.ComponentModel.Win32Exception: Le message reçu était inattendu ou formaté de façon incorrecte
   --- End of inner exception stack trace ---
   at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Security.SslState.ThrowIfExceptional()
   at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
   at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
   at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__47_1(IAsyncResult iar)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at System.Net.HttpWebRequest.SendRequest()
   at System.Net.HttpWebRequest.GetResponse()
   --- End of inner exception stack trace ---
   at System.Net.HttpWebRequest.GetResponse()
...

我认为,在TLS握手过程中所需的私钥所做的加密操作丢失了,它只是失败了.

我确实尝试在私有密钥属性中添加用于XML签名的RSA对象,但是在dotnet核心中,它以一个PlatformNotSupportedException结束.

代码语言:javascript
复制
cert.PrivateKey = myRSAObject; // simple

我想知道如果不使用第三方库就能做到这一点.

注意:翻译法文错误信息“消息是意外的或格式不正确。

谢谢。

(编辑:更好的格式)

EN

回答 1

Stack Overflow用户

发布于 2019-05-09 20:17:29

X509Certificate2是专为Windows设计的遗留类,目前还没有广泛可用的替代或正常的多平台替换。

当您使用X509Certificate2属性的byte[]值构造CKA_VALUE对象时,您只会得到没有私钥的证书。

最接近".NET兼容实现“的是实现从RSA派生的类,就像我在Pkcs11Interop.X509Store项目中所做的那样。它将与SignedXML类一起工作,但正如您已经发现的那样,它将不能用于大多数需要具有正确关联的PrivateKey属性的X509Certificate2对象的SSL类。

海事组织有三种选择:

  1. 切换到适当的.NET核心版本,并使用可拓法创建与RSA实现关联的X509Certificate2对象,@FilipNavara在他的评论中指出了这一点。这样的X509Certificate2对象可能(或者更确切地说可能)不适用于SSL实现。
  2. 使用PFX/PKCS#12文件,该文件包含SSL客户端证书,私钥受用户密码保护。这样的文件可以在X509Certificate2对象中正确地关联到.NET核心支持的大多数平台上的PrivateKey属性中。
  3. 查找或编写不需要具有关联X509Certificate2属性的PrivateKey对象的SSL客户端实现。我目前还不知道有这样的设计库。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56059386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档