我正在编写一个连接到我的WebAPI的.net核心(标准1.6)库。 WebApi需要客户端证书。
.net核心库是从Xamarin iOS应用程序调用的。
我无法终身发送带有客户端证书标头的HTTP请求。
我可以使用该库并在Windows机器上使用Visual Studio 2017中的客户端证书发布到API。
当我使用VS for Mac将同一个项目移动到我的Xamarin iOS应用程序时,我得到: 设置SslProtocol或添加客户端证书时“方法未实现”:
var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.SslProtocols = SslProtocols.Tls12;
handler.ClientCertificates.Add(new X509Certificate2(certificate));
相关图书馆:
using System.Net;
using System.Net.Http;
using System.Security;
using System.Security.Cryptography.X509Certificates;
非常感谢任何帮助。
答案 0 :(得分:1)
好吧,这花了我很长一段时间,但我能够在Web请求中发送客户端证书,以便在我们的服务器上用于客户端身份验证。
首先,正如Xamarin和.netCore一样令人敬畏,他们缺少很多方法.net开发人员习惯了。我无法构建可在Android和ios上运行的跨平台请求,例如HttpWebRequest。
对于ios,我创建了一个继承自以下的自定义类:NSUrlConnectionDataDelegate
然后我覆盖:
public override void WillSendRequestForAuthenticationChallenge(NSUrlConnection
connection, NSUrlAuthenticationChallenge challenge)
{
byte[] cert = System.IO.File.ReadAllBytes("clientCertificate.pfx");
NSUrlCredential credential = iSecurity.ImportPK12File(cert, "certPassword");
challenge.Sender.UseCredential(credential, challenge);
}
然后我创建了一个返回凭证的类:
//cert is a byte array of a .pfx file included in the resource file
//iSecurity Custom class
NSUrlCredential credential = iSecurity.ImportPK12File(cert, "certpassword");
public static NSUrlCredential ImportPK12File(byte[] fileBytes, string passPhrase)
{
var cert = new X509Certificate2(fileBytes, passPhrase);
var options = NSDictionary.FromObjectAndKey(NSObject.FromObject(passPhrase), SecImportExport.Passphrase);
NSDictionary[] importStatus;
SecStatusCode statusCode = SecImportExport.ImportPkcs12(fileBytes, options, out importStatus);
if(statusCode != SecStatusCode.Success){
throw new Exception("Error importing certificate. ");
}
NSObject obj = importStatus[0]["trust"];
IntPtr secTrustRef = obj.Handle;
var identityHandle = importStatus[0][SecImportExport.Identity];
var identity = new SecIdentity(identityHandle.Handle);
var certificate = new SecCertificate(cert.GetRawCertData());
SecCertificate[] certificates = { certificate };
return NSUrlCredential.FromIdentityCertificatesPersistance(identity, certificates, NSUrlCredentialPersistence.ForSession);
}
您也可以覆盖此方法并发送信用: public override void ReceivedAuthenticationChallenge(NSUrlConnection连接,NSUrlAuthenticationChallenge挑战) { base.ReceivedAuthenticationChallenge(连接,挑战); }
我可以将它移到那里但是为了解决这个问题,你创建了继承自的类的委托:NSUrlConnectionDataDelegate 并将其添加到您的连接。通过此连接触发的任何请求都将覆盖该方法并传递证书。