让X509Certificate2加载证书兼容Android端
使用 X509Certificate2 加载证书,一般使用pfx,在windows,linux什么的没什么问题
//加载证书
X509Certificate2 certificate = new X509Certificate2("xxx.pfx", "password", X509KeyStorageFlags.Exportable);
//服务端
SslStream sslStream = new SslStream(new NetworkStream(socket, false), false);
await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls13 | SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls, false);
//客户端
SslStream sslStream = new SslStream(new NetworkStream(socket, false), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
await sslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
{
EnabledSslProtocols = SslProtocols.Tls13 | SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls
});
private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
在Android却不可用,我们需要优化一下,改为pem。
//加载证书,我这里使用嵌入资源,也可以读文件
using Stream streamPublic = Assembly.GetExecutingAssembly().GetManifestResourceStream($"publickey.pem");
using Stream streamPrivate = Assembly.GetExecutingAssembly().GetManifestResourceStream($"privatekey.pem");
using StreamReader readerPublic = new StreamReader(streamPublic);
using StreamReader readerPrivate = new StreamReader(streamPrivate);
RSA rsaPrivateKey = RSA.Create();
rsaPrivateKey.ImportFromPem(readerPrivate.ReadToEnd());
using X509Certificate2 publicCert = X509Certificate2.CreateFromPem(readerPublic.ReadToEnd());
certificate = publicCert.CopyWithPrivateKey(rsaPrivateKey);
if (OperatingSystem.IsAndroid() == false)
{
byte[] pfxBytes = certificate.Export(X509ContentType.Pfx, "password");
certificate.Dispose();
certificate = new X509Certificate2(pfxBytes, "password");
}
//服务端,clientCertificateRequired 在android为true
SslStream sslStream = new SslStream(new NetworkStream(socket, false), false);
await sslStream.AuthenticateAsServerAsync(certificate, OperatingSystem.IsAndroid(), SslProtocols.Tls13 | SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls, false);
//客户端
SslStream sslStream = new SslStream(new NetworkStream(socket, false), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
await sslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
{
EnabledSslProtocols = SslProtocols.Tls13 | SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls,
CertificateRevocationCheckMode = X509RevocationMode.NoCheck,
//传入客户端证书
ClientCertificates = new X509CertificateCollection { certificate }
});
private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}