Просто чтобы уточнить, сертификат X.509 не содержит закрытого ключа.Слово сертификат иногда неправильно используется для обозначения комбинации сертификата и закрытого ключа, но они являются двумя различными объектами.Весь смысл использования сертификатов состоит в том, чтобы отправлять их более или менее открыто, без отправки секретного ключа, который должен храниться в секрете.С X509Certificate2
объектом может быть связан с ним закрытый ключ (через его свойство PrivateKey
), но это только удобство как часть дизайна этого класса.
В вашем первом примере кода BouncyCastle, newCert
на самом деле просто сертификат, а DotNetUtilities.ToX509Certificate(newCert)
построен только из сертификата.
Учитывая, что формат PKCS # 12 требует наличия закрытого ключа, я весьма удивленчто следующая часть даже работает (учитывая, что вы вызываете его на сертификате, который не может знать секретный ключ):
.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs12,
"password");
(gen.Generate(kp.Private)
подписывает сертификат с помощью секретного ключа, но нене помещайте закрытый ключ в сертификат, что не имеет смысла.)
Если вы хотите, чтобы ваш метод возвращал и сертификат, и закрытый ключ, вы можете либо:
- Вернуть
X509Certificate2
объект, в котором вы инициализировали свойство PrivateKey
- Построить хранилище PKCS # 12 и вернуть его содержимое
byte[]
(как если бы это был файл). Шаг 3 в отправленной вами ссылке ( mirror ) объясняет, как создать хранилище PKCS # 12.
Возвращение byte[]
(DER) структура самого сертификата X.509 не будет содержать закрытый ключ.
Если ваша основная задача (в соответствии с вашим тестовым примером) состоит в том, чтобы проверить, что сертификат был создан из пары ключей RSA, вы можетевместо этого проверьте тип его открытого ключа.