BouncyCastle 未定义长度 ASN1
Posted
技术标签:
【中文标题】BouncyCastle 未定义长度 ASN1【英文标题】:BouncyCastle undefined length ASN1 【发布时间】:2017-10-28 12:44:30 【问题描述】:我尝试从 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();
问题是,我得到以下异常:
经过几天的研究,我发现问题出在 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 包。
更新异常堆栈跟踪(将 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);
行之前使用此方法,则会出现“未定义长度编码”异常。离开了。但是现在,我得到了以下异常:
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 证书作为原始数据,效果很好!但它没有私钥..
【问题讨论】:
DER 中不允许有无限长度(DER 是 BER 的更受限制的子集)。 谢谢,但我如何在 c# 中使用您的提示? 您有来自 Bouncy Castle 的 DotNetUtilities 类吗?它可以将 bouncy cert 转换为 .Net cert,而不是您可以使用 .Net cert 来创建 X509Certificate2 我无法使用 DotNetUtilities。但是,如果我尝试从 BC X509Certificate 创建 X509Certificate2,效果会很好。仅当我添加包含私钥和 X509 证书的 PKCS 流时,我才会收到此错误。 如果可能的话,使用 DotNetUtilities,然后我可以创建一个 .Net 证书并将其添加到 Mono.Security PKCS12。因为如果我使用 Mono PKCS12,它会很好用。但问题是,我有 BC X509 证书。 【参考方案1】:我发现了一些关于您的问题的错误报告,其中列出了可能的解决方法。我自己没有合适的环境来测试这个 - 抱歉。但从历史看来,它似乎并没有真正得到解决:
-
Bugreport:
正如您所经历的那样,这明确说明了 BouncyCastle 的问题。 Sebastian Pouliot 在comment3 中发布了一个示例代码,他认为可以使用(或其中的一部分)来解决使用mono.security.dll 的问题。我不知道您的用例是否允许使用它。它与 MonoDroid 一起提供。 他在comment 中详细介绍,并在 github 上链接了示例代码:https://github.com/mono/mono/blob/master/mcs/tools/security/makecert.cs
-
还有其他人发布了这个问题。 BouncyCastle 没有明确提及:http://lists.ximian.com/pipermail/mono-bugs/2010-October/104908.html
他在帖子末尾的解决方法: [一旦你有正确的 PKCS#12] 引用:
将 byte[] PKCS#12 写入一个临时文件并用字符串加载它 构造函数。
更新 cmets 中提供的源代码
希望我的系统正常运行,因为它需要几个小时才能运行。但后来我得到了以下工作。
解决办法是把StoreBuilder的UseDEREncoding改为true
前面的小错误修复 发现:您输入了 string.empty 作为密码,但使用密码保护了证书。我认为这是不正确的。如果我输入密码,我会再次收到第一个错误 CryptographicException Certificate cannot becoded to valid certificate。
所以首先我改变了这个:
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.我尝试使用makecert.cs的一些代码,但无法编译。问题是,X509CertificateBuilder 有一些不可用的属性。例如:X509CertificateBuilder.SubjectPublicKey(错误:对类型“AsymmetricAlgorithm”的引用声称它是在“mscorlib”中定义的,但找不到) 2. 它对我不起作用。也许,PKCS#12 不正确!?我用保存文件的代码更新了我的问题,并创建了一个测试项目:1drv.ms/u/s!Aq2x4hOwAC2nl5J9ZzkHXyB-2-DObw @SeanStayn 看起来我需要一台 Mac 来解决这个问题?和一个VS2017?不能让它运行,因为我没有这两个。但是来自代码阅读的一个问题:就在异常行(215)之前,您创建了一个 certPassword 但您在 ctor 中使用了 string.empty?那不需要是 certPassword(你的 newGuid)吗? 你不需要mac,但你需要android sdk,xamarin等等。你是对的,在正常情况下我输入certPassword,但是为了尝试,我改变了它到 string.Empty. @SeanStayn 更新了我的答案。如果您因某种原因无法使用此解决方案或无法使用,请告诉我。 你应该把你的名字改成英雄!谢谢! :) 它完美地工作!!!!!! :) 关键是你的第一个改变。您应该在答案中提示“builder.SetUseDerEncoding(true);”是问题所在。 :)【参考方案2】:部分问题似乎在于 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 实现更加灵活:
(所以 Mono 只尝试了 .NET Framework / .NET Core 的一半)
根据 cmets,您似乎正在使用密码为空的 PFX,因此更改您的后 DER 规范化调用
new X509Certificate2(asn1ByteArray)
到
new X509Certificate2(asn1ByteArray, string.Empty)
应该解决问题的这个特定方面。
【讨论】:
感谢您的回答。我正在使用带有真实密码的密码参数,并且我已经尝试使用 string.Empty,但异常仍然存在。我用代码创建了一个测试项目。代码在 MyClass.cs 的 PCL 中:1drv.ms/u/s!Aq2x4hOwAC2nl5J9ZzkHXyB-2-DObw以上是关于BouncyCastle 未定义长度 ASN1的主要内容,如果未能解决你的问题,请参考以下文章
未捕获(承诺)TypeError:无法读取未定义的属性“长度”