Я пытаюсь построить X509Certificate2
из блога PKCS # 12 в байтовом массиве и получить довольно загадочную ошибку. Этот код работает в настольном приложении с правами администратора в Windows XP.
Трассировка стека выглядит следующим образом, но я потерялся, пытаясь устранить неполадки, потому что _LoadCertFromBlob
отмечен [MethodImpl(MethodImplOptions.InternalCall)]
.
System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
РЕДАКТИРОВАТЬ: БЛОБ - это настоящий PKCS # 12, сгенерированный BouncyCastle для С#, содержащий закрытый ключ RSA и сертификат (самозаверяемый или недавно зарегистрированный в ЦС) - то, что я пытаюсь сделать, - это преобразовать закрытый ключ и сертификат из библиотеки BouncyCastle в библиотеку System.Security.Cryptography, экспортируя их из одного и импортируя в другой, Этот код работает на подавляющем большинстве систем, на которые он был опробован; Я никогда не видел, чтобы эта конкретная ошибка была выбрана из этого конструктора. Это может быть какая-то экологическая странность в этой коробке.
РЕДАКТИРОВАТЬ 2: Ошибка возникает в другой среде в другом городе, и я не могу воспроизвести ее локально, так что я могу закончить тем, установка.
Так как вы спрашивали, вот фрагмент, о котором идет речь. Код принимает закрытый ключ и сертификат в представлении BouncyCastle, удаляет все предыдущие сертификаты для одного и того же Distinguished Name из личного хранилища ключей и импортирует новый закрытый ключ и сертификат в хранилище личных ключей через промежуточное PKCS # 12 blob.
// open the personal keystore
var msMyStore = new X509Store(StoreName.My);
msMyStore.Open(OpenFlags.MaxAllowed);
// remove any certs previously issued for the same DN
var oldCerts =
msMyStore.Certificates.Cast<X509Certificate2>()
.Where(c => X509Name
.GetInstance(Asn1Object.FromByteArray(c.SubjectName.RawData))
.Equivalent(CurrentCertificate.SubjectDN))
.ToArray();
if (oldCerts.Length > 0) msMyStore.RemoveRange(new X509Certificate2Collection(oldCerts));
// build a PKCS#12 blob from the private key and certificate
var pkcs12store = new Pkcs12StoreBuilder().Build();
pkcs12store.SetKeyEntry(_Pkcs12KeyName,
new AsymmetricKeyEntry(KeyPair.Private),
new[] {new X509CertificateEntry(CurrentCertificate)});
var pkcs12data = new MemoryStream();
pkcs12store.Save(pkcs12data, _Pkcs12Password.ToCharArray(), Random);
// and import it. this constructor call blows up
_MyCertificate2 = new X509Certificate2(pkcs12data.ToArray(),
_Pkcs12Password,
X509KeyStorageFlags.Exportable);
msMyStore.Add(_MyCertificate2);
msMyStore.Close();