C# 客户端证书在xamarin.android中不起作用
我正在尝试使用xamarin.android项目中的库建立mtls连接。在这个过程中,我在调用conResult.Wait(TimeSpan.FromSeconds(60))的Init方法中遇到了这样一个异常 {MQTTnet.Exceptions.MqttCommunicationException:身份验证失败,请参阅内部异常。-->System.Security.Authentication.AuthenticationException:身份验证失败,请参阅内部异常。-->System.Security.Cryptography.CryptographyException:捕获…} {System.Security.Cryptography.CryptographyException:在C# 客户端证书在xamarin.android中不起作用,c#,xamarin,xamarin.android,mtls,mqttnet,C#,Xamarin,Xamarin.android,Mtls,Mqttnet,我正在尝试使用xamarin.android项目中的库建立mtls连接。在这个过程中,我在调用conResult.Wait(TimeSpan.FromSeconds(60))的Init方法中遇到了这样一个异常 {MQTTnet.Exceptions.MqttCommunicationException:身份验证失败,请参阅内部异常。-->System.Security.Authentication.AuthenticationException:身份验证失败,请参阅内部异常。-->System.
MonoBtlsSslCtx.ProcessHandshake
-->System.NullReferenceException:对象引用未设置为对象的实例中捕获到未经处理的异常。
在Mono.Btls.monobtlssl.SetPrivateKey(Mono.Btls….}
这是我的代码:
public void Init()
{
ILoadCertificate certificateService = DependencyService.Get<ILoadCertificate>();
var cert = certificateService.LoadPemCertificate("certificate", "private_key");
Console.WriteLine(cert.GetRSAPrivateKey());
string clientId = Guid.NewGuid().ToString();
string mqttURI = "";
int mqttPort = 8883;
var factory = new MqttFactory();
var mqttClient = factory.CreateMqttClient();
bool disableServerValidation = true;
var tlsParameters = new MqttClientOptionsBuilderTlsParameters
{
UseTls = true,
Certificates = new[] { new X509Certificate(cert.Export(X509ContentType.Cert)) },
IgnoreCertificateChainErrors = disableServerValidation,
AllowUntrustedCertificates = disableServerValidation,
SslProtocol = System.Security.Authentication.SslProtocols.Tls12,
CertificateValidationHandler = (o) =>
{
return true;
},
};
var connectOptions = new MqttClientOptionsBuilder()
.WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V311)
.WithClientId(clientId)
.WithTcpServer(mqttURI, mqttPort)
.WithCommunicationTimeout(new TimeSpan(0, 2, 30))
.WithCleanSession()
.WithTls(tlsParameters)
.Build();
var conResult = mqttClient.ConnectAsync(connectOptions);
conResult.ContinueWith(r =>
{
Console.WriteLine(r.Result.ResultCode);
Console.WriteLine(r.Exception.StackTrace);
});
conResult.Wait(TimeSpan.FromSeconds(60));
var t = mqttClient.PublishAsync("events/test", "test");
t.ContinueWith(r =>
{
Console.WriteLine(r.Result.PacketIdentifier);
Console.WriteLine(r.Exception.StackTrace);
});
t.Wait();
}
//This methods is used to construct certificate:
public X509Certificate2 GetCertificate(string pemCert, string pemKey)
{
string fileNameCert = Path.Combine(Environment
.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), pemCert);
var pem = File.ReadAllText(fileNameCert);
string fileNameKey = Path.Combine(Environment
.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), pemKey);
var key = File.ReadAllText(fileNameKey);
var keyPair = (AsymmetricCipherKeyPair)new PemReader(new StringReader(key))
.ReadObject();
var cert = (Org.BouncyCastle.X509.X509Certificate)new PemReader(new
StringReader(pem)).ReadObject();
var builder = new Pkcs12StoreBuilder();
builder.SetUseDerEncoding(true);
var store = builder.Build();
var certEntry = new X509CertificateEntry(cert);
store.SetCertificateEntry("", certEntry);
store.SetKeyEntry("", new AsymmetricKeyEntry(keyPair.Private), new[] { certEntry });
byte[] data;
using (var ms = new MemoryStream())
{
store.Save(ms, Array.Empty<char>(), new SecureRandom());
data = ms.ToArray();
}
return new X509Certificate2(data);
}
public byte[] GetBytesFromPEM(string pemString, string type)
{
string header; string footer;
switch (type)
{
case "cert":
header = "-----BEGIN CERTIFICATE-----";
footer = "-----END CERTIFICATE-----";
break;
case "key":
header = "-----BEGIN RSA PRIVATE KEY-----";
footer = "-----END RSA PRIVATE KEY-----";
break;
default:
return null;
}
int start = pemString.IndexOf(header) + header.Length;
int end = pemString.IndexOf(footer, start) - start;
return Convert.FromBase64String(pemString.Substring(start, end));
}
这是一个自签名证书吗?我从AWS获得此证书。我有两个文件,分别是------开始证书------ddsbsb------结束证书------和------开始RSA私钥------DVD SBRS------结束RSA私钥------。据我从pems了解,我需要创建X509Certificate2。
string fileNameCert = Path.Combine(Environment
.GetFolderPath(Environment
.SpecialFolder.LocalApplicationData), certificatePath);
using var publicKey = new X509Certificate2(fileNameCert);
string fileNameKey = Path.Combine(Environment
.GetFolderPath(Environment
.SpecialFolder.LocalApplicationData), privateKeyPath);
using var rsa = RSA.Create();
byte[] keyBuffer =
GetBytesFromPEM(File.ReadAllText(fileNameKey), "key");
int o;
rsa.ImportRSAPrivateKey(keyBuffer, out o);
var keyPair = publicKey.CopyWithPrivateKey(rsa);
return new X509Certificate2(keyPair.Export(X509ContentType.Pkcs12));