C# 建立TCP连接时平台不支持异常

C# 建立TCP连接时平台不支持异常,c#,xamarin.forms,visual-studio-2019,C#,Xamarin.forms,Visual Studio 2019,升级到Visual Studio 2019后,我发现我现有的Xamarin应用程序无法再建立TCP连接 var pkcs12Store = new Pkcs12Store(); var certEntry = new X509CertificateEntry(BouncyCert); pkcs12Store.SetCertificateEntry(BouncyCert.SerialNumber.ToString(), ce

升级到Visual Studio 2019后,我发现我现有的Xamarin应用程序无法再建立TCP连接

            var pkcs12Store = new Pkcs12Store();
            var certEntry = new X509CertificateEntry(BouncyCert);

            pkcs12Store.SetCertificateEntry(BouncyCert.SerialNumber.ToString(), certEntry);
            pkcs12Store.SetKeyEntry(BouncyCert.SerialNumber.ToString(),
                new AsymmetricKeyEntry(KeyPair.Private), new[] { certEntry });

            X509Certificate2 keyedCert;

            using (MemoryStream pfxStream = new MemoryStream()) {
                pkcs12Store.Save(pfxStream, null, new SecureRandom());
                pfxStream.Seek(0, SeekOrigin.Begin);
                keyedCert = new X509Certificate2(pfxStream.ToArray(), "", X509KeyStorageFlags.Exportable);
            }

            return keyedCert;
经过一些研究,我发现VisualStudio2019附带了MSBuild 16,而VS2017附带了MSBuild 15

            var pkcs12Store = new Pkcs12Store();
            var certEntry = new X509CertificateEntry(BouncyCert);

            pkcs12Store.SetCertificateEntry(BouncyCert.SerialNumber.ToString(), certEntry);
            pkcs12Store.SetKeyEntry(BouncyCert.SerialNumber.ToString(),
                new AsymmetricKeyEntry(KeyPair.Private), new[] { certEntry });

            X509Certificate2 keyedCert;

            using (MemoryStream pfxStream = new MemoryStream()) {
                pkcs12Store.Save(pfxStream, null, new SecureRandom());
                pfxStream.Seek(0, SeekOrigin.Begin);
                keyedCert = new X509Certificate2(pfxStream.ToArray(), "", X509KeyStorageFlags.Exportable);
            }

            return keyedCert;
在为我的RSA系统加密生成证书和密钥对后使用这段代码之前:

var cert = new X509Certificate2(DotNetUtilities.ToX509Certificate(bcCert)) 
    { PrivateKey = DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)keyPair.Private) };
            var pkcs12Store = new Pkcs12Store();
            var certEntry = new X509CertificateEntry(BouncyCert);

            pkcs12Store.SetCertificateEntry(BouncyCert.SerialNumber.ToString(), certEntry);
            pkcs12Store.SetKeyEntry(BouncyCert.SerialNumber.ToString(),
                new AsymmetricKeyEntry(KeyPair.Private), new[] { certEntry });

            X509Certificate2 keyedCert;

            using (MemoryStream pfxStream = new MemoryStream()) {
                pkcs12Store.Save(pfxStream, null, new SecureRandom());
                pfxStream.Seek(0, SeekOrigin.Begin);
                keyedCert = new X509Certificate2(pfxStream.ToArray(), "", X509KeyStorageFlags.Exportable);
            }

            return keyedCert;
使用Visual Studio 2019,您无法设置私钥。这可以在中的反编译X509Certificate2.cs中看到
C:\ProgramFiles(x86)\MicrosoftVisualStudio\2019\Professional\Common7\IDE\ReferenceAssembly\Microsoft\Framework\MonoAndroid\v1.0\System.dll

            var pkcs12Store = new Pkcs12Store();
            var certEntry = new X509CertificateEntry(BouncyCert);

            pkcs12Store.SetCertificateEntry(BouncyCert.SerialNumber.ToString(), certEntry);
            pkcs12Store.SetKeyEntry(BouncyCert.SerialNumber.ToString(),
                new AsymmetricKeyEntry(KeyPair.Private), new[] { certEntry });

            X509Certificate2 keyedCert;

            using (MemoryStream pfxStream = new MemoryStream()) {
                pkcs12Store.Save(pfxStream, null, new SecureRandom());
                pfxStream.Seek(0, SeekOrigin.Begin);
                keyedCert = new X509Certificate2(pfxStream.ToArray(), "", X509KeyStorageFlags.Exportable);
            }

            return keyedCert;

在此之后,我发现了一个
ConvertBouncyCert
方法,该方法将返回一个
X509Certificate2
包装器,该包装器将在生成的X509Certificate周围附加私钥,但我仍然收到一个
无法解码的
异常。

Jeremy的库包含用于转换X509Certificate的代码进入X509Certificate2:

            var pkcs12Store = new Pkcs12Store();
            var certEntry = new X509CertificateEntry(BouncyCert);

            pkcs12Store.SetCertificateEntry(BouncyCert.SerialNumber.ToString(), certEntry);
            pkcs12Store.SetKeyEntry(BouncyCert.SerialNumber.ToString(),
                new AsymmetricKeyEntry(KeyPair.Private), new[] { certEntry });

            X509Certificate2 keyedCert;

            using (MemoryStream pfxStream = new MemoryStream()) {
                pkcs12Store.Save(pfxStream, null, new SecureRandom());
                pfxStream.Seek(0, SeekOrigin.Begin);
                keyedCert = new X509Certificate2(pfxStream.ToArray(), "", X509KeyStorageFlags.Exportable);
            }

            return keyedCert;
您需要创建Pkcs12StoreBuilder对象并将DER编码设置为true

            var pkcs12Store = new Pkcs12Store();
            var certEntry = new X509CertificateEntry(BouncyCert);

            pkcs12Store.SetCertificateEntry(BouncyCert.SerialNumber.ToString(), certEntry);
            pkcs12Store.SetKeyEntry(BouncyCert.SerialNumber.ToString(),
                new AsymmetricKeyEntry(KeyPair.Private), new[] { certEntry });

            X509Certificate2 keyedCert;

            using (MemoryStream pfxStream = new MemoryStream()) {
                pkcs12Store.Save(pfxStream, null, new SecureRandom());
                pfxStream.Seek(0, SeekOrigin.Begin);
                keyedCert = new X509Certificate2(pfxStream.ToArray(), "", X509KeyStorageFlags.Exportable);
            }

            return keyedCert;
            var pkcs12StoreBuilder = new Pkcs12StoreBuilder();

            pkcs12StoreBuilder.SetUseDerEncoding(true);
            var pkcs12Store = pkcs12StoreBuilder.Build();

            var certificateEntry = new X509CertificateEntry(bouncyCert);
这在解释DER及其在密码学和RSA系统中的所有组件方面做得非常好

            var pkcs12Store = new Pkcs12Store();
            var certEntry = new X509CertificateEntry(BouncyCert);

            pkcs12Store.SetCertificateEntry(BouncyCert.SerialNumber.ToString(), certEntry);
            pkcs12Store.SetKeyEntry(BouncyCert.SerialNumber.ToString(),
                new AsymmetricKeyEntry(KeyPair.Private), new[] { certEntry });

            X509Certificate2 keyedCert;

            using (MemoryStream pfxStream = new MemoryStream()) {
                pkcs12Store.Save(pfxStream, null, new SecureRandom());
                pfxStream.Seek(0, SeekOrigin.Begin);
                keyedCert = new X509Certificate2(pfxStream.ToArray(), "", X509KeyStorageFlags.Exportable);
            }

            return keyedCert;