@@ -17,29 +17,56 @@ public static X509Certificate2 FindByThumbprint(string thumbprint)
1717 return store . Certificates . Find ( X509FindType . FindByThumbprint , thumbprint , false ) . Single ( ) ;
1818 }
1919
20+ public static string ExportCertificateToPem ( X509Certificate2 cert )
21+ {
22+ return cert . ExportCertificatePem ( ) ;
23+ }
24+
25+ public static string ExportPublicKeyToPem ( X509Certificate2 cert )
26+ {
27+ using var rsa = ( AsymmetricAlgorithm ) cert . GetRSAPublicKey ( ) ?? cert . GetECDsaPublicKey ( ) ;
28+ return rsa . ExportSubjectPublicKeyInfoPem ( ) ;
29+ }
30+
2031 public static string ExportPrivateKeyToPem ( X509Certificate2 cert )
2132 {
2233 if ( ! cert . HasPrivateKey )
2334 throw new InvalidOperationException ( "No private key found in certificate: " + cert . Subject ) ;
2435
25- var rsa = cert . GetRSAPrivateKey ( ) ;
36+ using var tmpCert = ToExportable ( cert ) ;
37+ using var rsa = ( AsymmetricAlgorithm ) tmpCert . GetRSAPrivateKey ( ) ?? tmpCert . GetECDsaPrivateKey ( ) ;
2638 if ( rsa is RSACng rsaCng )
2739 {
28- try
29- {
30- var parameters = rsaCng . ExportParameters ( true ) ;
31- using var rsaTemp = RSA . Create ( ) ;
32- rsaTemp . ImportParameters ( parameters ) ;
33- return rsaTemp . ExportPkcs8PrivateKeyPem ( ) ;
34- }
35- catch ( Exception ex )
36- {
37- throw new InvalidOperationException ( "Private key can't be exported: " + cert . Subject , ex ) ;
38- }
40+ using var rsaTemp = ToRsa ( rsaCng ) ;
41+ return rsaTemp . ExportPkcs8PrivateKeyPem ( ) ;
3942 }
4043
4144 return rsa . ExportPkcs8PrivateKeyPem ( ) ;
45+ }
4246
47+ private static X509Certificate2 ToExportable ( X509Certificate2 cert )
48+ {
49+ var tmpPwd = Guid . NewGuid ( ) . ToString ( "N" ) ;
50+ var content = cert . Export ( X509ContentType . Pkcs12 , tmpPwd ) ;
51+ return new X509Certificate2 (
52+ content ,
53+ tmpPwd ,
54+ X509KeyStorageFlags . Exportable | X509KeyStorageFlags . PersistKeySet ) ;
55+ }
56+
57+ private static RSA ToRsa ( RSACng cng )
58+ {
59+ var parameters = cng . ExportParameters ( true ) ;
60+ var rsaTemp = RSA . Create ( ) ;
61+ try
62+ {
63+ rsaTemp . ImportParameters ( parameters ) ;
64+ }
65+ catch
66+ {
67+ rsaTemp . Dispose ( ) ;
68+ throw ;
69+ }
4370 }
4471 }
4572}
0 commit comments