internal static ECDsa MakeExportable(this ECDsa ecdsa)
        {
            if (ecdsa is ECDsaCng dsaCng)
            {
                const CngExportPolicies Exportability =
                    CngExportPolicies.AllowExport |
                    CngExportPolicies.AllowPlaintextExport;

                if ((dsaCng.Key.ExportPolicy & Exportability) == CngExportPolicies.AllowExport)
                {
                    ECDsa copy = ECDsa.Create();

                    copy.ImportEncryptedPkcs8PrivateKey(
                        nameof(MakeExportable),
                        ecdsa.ExportEncryptedPkcs8PrivateKey(
                            nameof(MakeExportable),
                            new PbeParameters(
                                PbeEncryptionAlgorithm.TripleDes3KeyPkcs12,
                                HashAlgorithmName.SHA1,
                                2048)),
                        out _);
                    return(copy);
                }
            }

            return(ecdsa);
        }
Beispiel #2
0
        /// <summary>
        /// Returns a byte array containing the private key in PEM format.
        /// </summary>
        public static byte[] ExportPrivateKeyAsPEM(
            X509Certificate2 certificate,
            string password = null
            )
        {
            byte[] exportedPkcs8PrivateKey = null;
            using (RSA rsaPrivateKey = certificate.GetRSAPrivateKey())
            {
                if (rsaPrivateKey != null)
                {
                    // write private key as PKCS#8
                    exportedPkcs8PrivateKey = String.IsNullOrEmpty(password) ?
                                              rsaPrivateKey.ExportPkcs8PrivateKey() :
                                              rsaPrivateKey.ExportEncryptedPkcs8PrivateKey(password.ToCharArray(),
                                                                                           new PbeParameters(PbeEncryptionAlgorithm.TripleDes3KeyPkcs12, HashAlgorithmName.SHA1, 2000));
                }
                else
                {
                    using (ECDsa ecdsaPrivateKey = certificate.GetECDsaPrivateKey())
                    {
                        if (ecdsaPrivateKey != null)
                        {
                            // write private key as PKCS#8
                            exportedPkcs8PrivateKey = String.IsNullOrEmpty(password) ?
                                                      ecdsaPrivateKey.ExportPkcs8PrivateKey() :
                                                      ecdsaPrivateKey.ExportEncryptedPkcs8PrivateKey(password.ToCharArray(),
                                                                                                     new PbeParameters(PbeEncryptionAlgorithm.TripleDes3KeyPkcs12, HashAlgorithmName.SHA1, 2000));
                        }
                    }
                }
            }

            return(EncodeAsPEM(exportedPkcs8PrivateKey,
                               String.IsNullOrEmpty(password) ? "PRIVATE KEY" : "ENCRYPTED PRIVATE KEY"));
        }
        private ECParameters PlaintextExportParametersIncludingPrivateRegardlessOfExportPolicy(ECDsa ecdsaKey)
        {
            if (ecdsaKey is ECDsaCng ecdsaCng && CngKeyNeedsPlaintextWorkaround(ecdsaCng.Key))
            {
                EnsureCanBeExported(ecdsaCng.Key);

                // Workaround if AllowExport is set, but missing AllowPlaintextExport
                var password    = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString());
                var exportedKey = ecdsaKey.ExportEncryptedPkcs8PrivateKey(password, _pbeParameters);
                using var tmpEcdsaKey = ECDsa.Create() ?? throw new CertificatePrivateKeyBytesLoaderException("Unable to create an instance of the default ECDsa implementation");
                tmpEcdsaKey.ImportEncryptedPkcs8PrivateKey(password, exportedKey, out _);
                return(tmpEcdsaKey.ExportParameters(true));
            }

            return(ecdsaKey.ExportParameters(true));
        }