# .NET跨平台让SSL证书兼容Android

让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;
}