BouncyCastle 未定义长度 ASN1

BouncyCastle undefined length ASN1

我尝试从 BountyCastle X509Certificate 和 PKCS12 获取 X509Certificate2。我使用以下代码:

 certificate = new X509Certificate2(rawData, password, storageFlags);

我生成原始数据,如下所示:

using (MemoryStream pfxData = new MemoryStream())
{
   X509CertificateEntry[] chain = new X509CertificateEntry[1];

   chain[0] = new X509CertificateEntry(x509);
   pkcsStore.SetKeyEntry(applicationName, new AsymmetricKeyEntry(subjectKeyPair.Private), chain);
   pkcsStore.Save(pfxData, passcode.ToCharArray(), random);
   var rawData = pfx.ToArray();
}

问题是,我遇到以下异常:

经过几天的研究,我发现问题出在 ASN1 的 Mono 实现上。此实现不允许 "Undefined length encoding"。如果我在 Windows 上使用代码,效果很好。

我的问题

有什么方法可以将 pfxData 流转换为有效的 ASN1 结构吗?

我已经用下面的代码试过了:

Asn1InputStream asn1InputStream = new Asn1InputStream(pfxData);
var asn1Object = asn1InputStream.ReadObject();

MemoryStream memoryStream = new MemoryStream();
new Asn1OutputStream((Stream)memoryStream).WriteObject(asn1Object);
var asn1ByteArray = memoryStream.ToArray();

certificate = new X509Certificate2(asn1ByteArray);

但是使用这段代码,我得到以下异常:

"Index was out of range. Must be non-negative and less than the size of the collection.\nParameter name: startIndex"

我将 Xamarin PCL 与 .NET Standard 1.3 一起使用,我只能使用 "Portable.BouncyCastle" Nuget 包。

更新异常堆栈跟踪(将 BER 转换为 DER):

05-28 15:19:54.895 D/Mono    ( 3808): Assembly Ref addref Mono.Security[0x9b4fe080] -> System[0xac8de400]: 17
05-28 15:19:54.957 I/mono-stdout( 3808): System.AggregateException: One or more errors occurred. ---> System.Security.Cryptography.CryptographicException: Unable to decode certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
System.AggregateException: One or more errors occurred. ---> System.Security.Cryptography.CryptographicException: Unable to decode certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: startIndex
  at System.String.IndexOf (System.String value, System.Int32 startIndex, System.Int32 count, System.StringComparison comparisonType) [0x0002a] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.String.IndexOf (System.String value, System.Int32 startIndex, System.StringComparison comparisonType) [0x00009] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.String.IndexOf (System.String value, System.Int32 startIndex) [0x00000] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at Mono.Security.X509.X509Certificate.PEM (System.String type, System.Byte[] data) [0x00030] in <2940be14d5a1446694e2193e9029b558>:0 
  at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x00014] in <2940be14d5a1446694e2193e9029b558>:0 
   --- End of inner exception stack trace ---
  at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x0002f] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.958 I/mono-stdout( 3808): Parameter name: startIndex
  at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x0000b] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
   --- End of inner exception stack trace ---
  at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00031] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Helper2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, System.Boolean disableProvider) [0x00020] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00000] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor (System.Byte[] rawData) [0x00011] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.958 I/mono-stdout( 3808):   at System.String.IndexOf (System.String value, System.Int32 startIndex, System.Int32 count, System.StringComparison comparisonType) [0x0002a] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String password, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] domainNames, System.UInt16 keySize, System.DateTime startTime, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits, System.Boolean isCA, System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCAKeyCert) [0x003b5] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:517 
05-28 15:19:54.958 I/mono-stdout( 3808):   at System.String.IndexOf (System.String value, System.Int32 startIndex, System.StringComparison comparisonType) [0x00009] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] serverDomainNames, System.UInt16 keySize, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits) [0x00001] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:318 
  at APP.Models.Services.ACommunicationService+<ACommunicationServiceAsync>d__18.MoveNext () [0x00972] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:214 
   --- End of inner exception stack trace ---
05-28 15:19:54.959 I/mono-stdout( 3808):   at System.String.IndexOf (System.String value, System.Int32 startIndex) [0x00000] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00011] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.Threading.Tasks.Task.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) [0x00043] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.Threading.Tasks.Task.Wait () [0x00000] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at APP.Models.Services.ACommunicationService..ctor (PCLStorage.IFolder rootFolder) [0x00010] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:46 
05-28 15:19:54.959 I/mono-stdout( 3808):   at Mono.Security.X509.X509Certificate.PEM (System.String type, System.Byte[] data) [0x00030] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.959 I/mono-stdout( 3808):   at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x00014] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.959 I/mono-stdout( 3808):    --- End of inner exception stack trace ---
05-28 15:19:54.959 I/mono-stdout( 3808):   at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x0002f] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.959 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x0000b] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
---> (Inner Exception #0) System.Security.Cryptography.CryptographicException: Unable to decode certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
05-28 15:19:54.961 I/mono-stdout( 3808):    --- End of inner exception stack trace ---
05-28 15:19:54.961 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00031] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.961 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Helper2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, System.Boolean disableProvider) [0x00020] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.962 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00000] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.962 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor (System.Byte[] rawData) [0x00011] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
Parameter name: startIndex
05-28 15:19:54.963 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String password, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] domainNames, System.UInt16 keySize, System.DateTime startTime, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits, System.Boolean isCA, System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCAKeyCert) [0x003b5] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:517 
05-28 15:19:54.963 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] serverDomainNames, System.UInt16 keySize, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits) [0x00001] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:318 
05-28 15:19:54.964 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService+<ACommunicationServiceAsync>d__18.MoveNext () [0x00972] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:214 
05-28 15:19:54.964 I/mono-stdout( 3808):    --- End of inner exception stack trace ---
05-28 15:19:54.965 I/mono-stdout( 3808):   at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00011] in <d18287e1d683419a8ec3216fd78947b9>:0 
05-28 15:19:54.965 I/mono-stdout( 3808):   at System.Threading.Tasks.Task.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) [0x00043] in <d18287e1d683419a8ec3216fd78947b9>:0 
05-28 15:19:54.965 I/mono-stdout( 3808):   at System.Threading.Tasks.Task.Wait () [0x00000] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.String.IndexOf (System.String value, System.Int32 startIndex, System.Int32 count, System.StringComparison comparisonType) [0x0002a] in <d18287e1d683419a8ec3216fd78947b9>:0 
05-28 15:19:54.965 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService..ctor (PCLStorage.IFolder rootFolder) [0x00010] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:46 
05-28 15:19:54.966 I/mono-stdout( 3808): ---> (Inner Exception #0) System.Security.Cryptography.CryptographicException: Unable to decode certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
05-28 15:19:54.966 I/mono-stdout( 3808): Parameter name: startIndex
05-28 15:19:54.967 I/mono-stdout( 3808):   at System.String.IndexOf (System.String value, System.Int32 startIndex, System.Int32 count, System.StringComparison comparisonType) [0x0002a] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.String.IndexOf (System.String value, System.Int32 startIndex, System.StringComparison comparisonType) [0x00009] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.String.IndexOf (System.String value, System.Int32 startIndex) [0x00000] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at Mono.Security.X509.X509Certificate.PEM (System.String type, System.Byte[] data) [0x00030] in <2940be14d5a1446694e2193e9029b558>:0 
  at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x00014] in <2940be14d5a1446694e2193e9029b558>:0 
   --- End of inner exception stack trace ---
  at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x0002f] in <2940be14d5a1446694e2193e9029b558>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x0000b] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
   --- End of inner exception stack trace ---
  at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certif
icates.X509KeyStorageFlags keyStorageFlags) [0x00031] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Helper2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, System.Boolean disableProvider) [0x00020] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00000] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor (System.Byte[] rawData) [0x00011] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String password, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] domainNames, System.UInt16 keySize, System.DateTime startTime, 
System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits, System.Boolean isCA, System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCAKeyCert) [0x003b5] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:517 
  at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] serverDomainNames, System.UInt16 keySize, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits) [0x00001] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:318 
  at APP.Models.Services.ACommunicationService+<ACommunicationServiceAsync>d__18.MoveNext () [0x00972] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:214 <---
05-28 15:19:54.968 I/mono-stdout( 3808):   at System.String.IndexOf (System.String value, System.Int32 startIndex, System.StringComparison comparisonType) [0x00009] in <d18287e1d683419a8ec3216fd78947b9>:0 
05-28 15:19:54.969 I/mono-stdout( 3808):   at System.String.IndexOf (System.String value, System.Int32 startIndex) [0x00000] in <d18287e1d683419a8ec3216fd78947b9>:0 
05-28 15:19:54.969 I/mono-stdout( 3808):   at Mono.Security.X509.X509Certificate.PEM (System.String type, System.Byte[] data) [0x00030] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.969 I/mono-stdout( 3808):   at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x00014] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.969 I/mono-stdout( 3808):    --- End of inner exception stack trace ---
05-28 15:19:54.969 I/mono-stdout( 3808):   at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x0002f] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.969 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x0000b] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.969 I/mono-stdout( 3808):    --- End of inner exception stack trace ---
05-28 15:19:54.969 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00031] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.970 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Helper2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, System.Boolean disableProvider) [0x00020] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.970 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00000] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.970 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor (System.Byte[] rawData) [0x00011] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.970 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String password, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] domainNames, System.UInt16 keySize, System.DateTime startTime, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits, System.Boolean isCA, System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCAKeyCert) [0x003b5] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:517 
05-28 15:19:54.971 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] serverDomainNames, System.UInt16 keySize, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits) [0x00001] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:318 
05-28 15:19:54.971 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService+<ACommunicationServiceAsync>d__18.MoveNext () [0x00972] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:214 <---

编辑: 我在 BouncyCastle GitHub 中发布了同样的问题:BouncyCastle GitHub

编辑 2: 我已经测试保存 PKCS 并使用字符串构造函数创建 X509Certificate2,如下所示:

var pkcsPath = pkcsStorePath + "/pkcs.p12";
File.WriteAllBytes(pkcsPath, pfxData.ToArray());

// Exception is thrown on this line (Undefined length):
certificate = new X509Certificate2(pkcsPath, string.Empty);

编辑 3: 我在 BouncyCastle 库中找到了方法 var util = Pkcs12Utilities.ConvertToDefiniteLength(pfxData.ToArray(), certPassword.ToCharArray());,如果我在 File.WriteAllBytes(pkcsPath, util); 行之前使用此方法,则异常"Undefined length encoding." 不见了。但是现在,我得到以下异常:

06-01 21:05:54.903 I/mono-stdout(31001): System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate.
System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate.
  at Mono.Security.X509.X509Certificate.Parse (System.Byte[] data) [0x0003b] in <2940be14d5a1446694e2193e9029b558>:0 
   --- End of inner exception stack trace ---
  at Mono.Security.X509.X509Certificate.Parse (System.Byte[] data) [0x00322] in <2940be14d5a1446694e2193e9029b558>:0 
  at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x00030] in <2940be14d5a1446694e2193e9029b558>:0 
06-01 21:05:54.905 I/mono-stdout(31001):   at Mono.Security.X509.X509Certificate.Parse (System.Byte[] data) [0x0003b] in <2940be14d5a1446694e2193e9029b558>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00041] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Helper2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, System.Boolean disableProvider) [0x00020] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00000] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor (System.Byte[] rawData, System.String password) [0x00011] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at Pkcs12TestProject.MyClass.CreateCertific
ate (System.String storeType, System.String storePath, System.String password, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] domainNames, System.UInt16 keySize, System.DateTime startTime, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits, System.Boolean isCA, System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCAKeyCert, System.String pkcsStorePath) [0x00377] in C:\OneDrive\VS\Pkcs12TestProject\Pkcs12TestProject\Pkcs12TestProject\MyClass.cs:223 
06-01 21:05:54.906 I/mono-stdout(31001):    --- End of inner exception stack trace ---
06-01 21:05:54.906 I/mono-stdout(31001):   at Mono.Security.X509.X509Certificate.Parse (System.Byte[] data) [0x00322] in <2940be14d5a1446694e2193e9029b558>:0 
06-01 21:05:54.906 I/mono-stdout(31001):   at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x00030] in <2940be14d5a1446694e2193e9029b558>:0 
06-01 21:05:54.906 I/mono-stdout(31001):   at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00041] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
06-01 21:05:54.906 I/mono-stdout(31001):   at System.Security.Cryptography.X509Certificates.X509Helper2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, System.Boolean disableProvider) [0x00020] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
06-01 21:05:54.906 I/mono-stdout(31001):   at System.Security.Cryptography.X509Certificates.X509Certificate2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00000] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
06-01 21:05:54.907 I/mono-stdout(31001):   at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor (System.Byte[] rawData, System.String password) [0x00011] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
06-01 21:05:54.907 I/mono-stdout(31001):   at Pkcs12TestProject.MyClass.CreateCertificate (System.String storeType, System.String storePath, System.String password, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] domainNames, System.UInt16 keySize, System.DateTime startTime, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits, System.Boolean isCA, System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCAKeyCert, System.String pkcsStorePath) [0x00377] in C:\OneDrive\VS\Pkcs12TestProject\Pkcs12TestProject\Pkcs12TestProject\MyClass.cs:223 

编辑 4: 如果我在 X509Certificate2 方法中使用来自 BountyCastle 的 X509 证书作为原始数据,效果很好!但是没有私钥..

我发现了一些关于您的问题的错误报告,其中列出了可能的解决方法。我自己没有合适的环境来测试这个 - 抱歉。但是从历史上看好像还没有真正解决:

  1. Bugreport:

这明确说明了 BouncyCastle 的问题,就像您遇到的那样。 Sebastian Pouliot post 是 comment3 中的示例代码,他认为可以使用(或部分代码)解决使用 mono.security.dll 的问题。我不知道你的用例是否允许使用它。它与 MonoDroid 一起提供。
他在 comment and has the example code linked on github: https://github.com/mono/mono/blob/master/mcs/tools/security/makecert.cs

中详细介绍了
  1. 还有其他人 post 对此提出了问题。未明确提及 BouncyCastle:http://lists.ximian.com/pipermail/mono-bugs/2010-October/104908.html

他的 解决方法 在 post 的结尾:
[一旦您拥有正确的 PKCS#12] 引用:

Write the byte[] PKCS#12 into a temporary file and load it with string constructor.


更新评论中提供的源代码

希望我的系统能正常工作,因为它花了几个小时才得到它 运行。但后来我得到了以下工作。

The solution is to change the StoreBuilder to UseDEREncoding to true

前面的小错误修复
发现:您输入了 string.empty 作为密码,但使用密码保护了证书。我认为这是不正确的。如果我输入密码,我会再次遇到第一个错误 CryptographicException Certificate cannot be coded to valid certificate.

所以首先我改变了这个:

certificate = new X509Certificate2(pkcsPath, string.Empty);

certificate = new X509Certificate2(pkcsPath, certPassword);

修复
现在我不知道这是否是您想要的,但在更改它之后我没有得到异常,而是得到了一个证书对象。

"using memory stream" 块的完整变化最终如下所示:

using (MemoryStream pfxData = new MemoryStream())
{
    // **Change 1**: The DER Encoding is enabled on the
    // store builder
    Pkcs12StoreBuilder builder = new Pkcs12StoreBuilder();
    builder.SetUseDerEncoding(true);
    Pkcs12Store pkcsStore = builder.Build();
    // change - end

    X509CertificateEntry[] chain = new X509CertificateEntry[1];
    string certPassword = Guid.NewGuid().ToString();
    chain[0] = new X509CertificateEntry(x509);
    pkcsStore.SetKeyEntry(applicationName, new AsymmetricKeyEntry(subjectKeyPair.Private), chain);
    pkcsStore.Save(pfxData, certPassword.ToCharArray(), random);

    var pkcsPath = pkcsStorePath + "/pkcs.p12";

    File.WriteAllBytes(pkcsPath, pfxData.ToArray());

    // **Change 2**: Use certificate password
    certificate = new X509Certificate2(pkcsPath, certPassword);
    // **Change 3**: Possible to use array instead of filename
    // works as well. Just uncomment
    //certificate = new X509Certificate2(pfxData.ToArray(), certPassword);

}

部分问题似乎是 Mono 的 X509Certificate2 byte[] 构造函数与 .NET Framework 的 X509Certificate2 byte[] 构造函数的行为不同。

浏览 mono source 看起来 X509Certificate2(byte[]) 将尝试加载为 X.509(个人)证书,然后加载为具有 null 的 PFX(相对于空)密码。

让我最困惑的是你的调用堆栈,我希望重现,是它尝试了 PEM 解码......这应该只在第一个字节不是 0x30 时发生(per the source ), 但 0x30 也应该是 PFX 的第一个字节。 (然后是他们没有找到 -----BEGIN CERTIFICATE----- 导致 ArgumentOutOfRangeException 的错误处理,这让我走上了一条糟糕的道路。哦,好吧。)

new X509Certificate2(byte[])的.NET Framework实现更加灵活:

  • X.509 DER
  • X.509 PEM
  • PFX 空密码
  • PFX空密码
  • PKCS#7 SignedCms 签署者证书
  • AuthentiCode 签名者证书

(所以 Mono 只尝试了 .NET Framework / .NET Core 所做的事情的一半)

根据评论,您似乎正在使用密码为空的 PFX,因此请将您的 post-DER 规范化调用从

更改为
new X509Certificate2(asn1ByteArray)

new X509Certificate2(asn1ByteArray, string.Empty)

应该解决问题的这个特定方面。