BouncyCastle未定义长度ASN1

时间:2017-05-27 21:08:35

标签: c# xamarin mono portable-class-library x509

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

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

我生成rawData,如下所示:

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();
}

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

enter image description here

经过几天的研究,我发现问题是基于ASN1的Mono实现。此实现不允许"未定义长度编码"。如果我在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);

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

  

"指数超出范围。必须是非负数且小于集合的大小。\ n参数名称:startIndex"

我使用Xamarin PCL和.NET Standard 1.3,我只能使用" Portable.BouncyCastle" Nuget包。

UPDATE异常堆栈跟踪(将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);行之前使用此方法,则异常&#34;未定义长度编码。&#34;离开了。但现在,我得到以下例外:

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证书作为rawdata,那么效果很好!但它没有私钥..

2 个答案:

答案 0 :(得分:2)

我发现了一些关于您的问题的错误报告,并列出了可能的解决方法。我自己没有适当的环境来测试 - 抱歉。但从历史来看,它似乎还没有真正得到解决:

  1. Bugreport
  2. 这明确说明了BouncyCastle的问题就像您体验一样。 Sebastian Pouliot在comment3中发布了一个示例代码,他认为可以使用它(或部分代码)来解决使用mono.security.dll的问题。我不知道你的用例是否允许使用它。它随MonoDroid一起发货 他详细介绍了这个comment,并在github上链接了示例代码:https://github.com/mono/mono/blob/master/mcs/tools/security/makecert.cs

    1. 还有其他人发布了此问题。未明确提及BouncyCastle:http://lists.ximian.com/pipermail/mono-bugs/2010-October/104908.html
    2. 帖子末尾的解决方法
      [一旦你有了正确的PKCS#12]引用:

        

      将byte [] PKCS#12写入临时文件并使用字符串加载它   构造

      在评论中提供的来源更新

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

      解决方案是将StoreBuilder更改为UseDEREncoding为true。

      预先小错误修正
      查找:您输入string.empty作为密码但使用密码保护证书。我认为这不正确。如果我输入密码,我再次收到第一个错误CryptographicException证书无法编码为有效证书。

      所以首先我改变了这个:

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

      certificate = new X509Certificate2(pkcsPath, certPassword);
      

      <强>修正
      现在我不知道这是否是你想要的但是在更改之后我没有得到例外而是证书对象。

      “使用内存流”块的完整更改最终看起来像这样:

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

答案 1 :(得分:0)

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

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

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

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

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

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

基于评论,您似乎正在使用带有空密码的PFX,因此更改您的后DER标准化呼叫

new X509Certificate2(asn1ByteArray)

new X509Certificate2(asn1ByteArray, string.Empty)

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