Пример #1
0
 /// <summary>
 /// Imports an RFC 7468 PEM-encoded key, replacing the keys for this object.
 /// </summary>
 /// <param name="input">The PEM text of the key to import.</param>
 /// <exception cref="ArgumentException">
 /// <para>
 ///   <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
 /// </para>
 /// <para>
 ///   -or-
 /// </para>
 /// <para>
 ///   <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
 /// </para>
 /// <para>
 ///     -or-
 /// </para>
 /// <para>
 ///   <paramref name="input"/> contains an encrypted PEM-encoded key.
 /// </para>
 /// </exception>
 /// <remarks>
 ///   <para>
 ///   Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
 ///   are found, an exception is raised to prevent importing a key when
 ///   the key is ambiguous.
 ///   </para>
 ///   <para>
 ///   This method supports the following PEM labels:
 ///   <list type="bullet">
 ///     <item><description>PUBLIC KEY</description></item>
 ///     <item><description>PRIVATE KEY</description></item>
 ///     <item><description>RSA PRIVATE KEY</description></item>
 ///     <item><description>RSA PUBLIC KEY</description></item>
 ///   </list>
 ///   </para>
 /// </remarks>
 public override void ImportFromPem(ReadOnlySpan <char> input)
 {
     PemKeyHelpers.ImportPem(input, label => {
         if (label.SequenceEqual(PemLabels.RsaPrivateKey))
         {
             return(ImportRSAPrivateKey);
         }
         else if (label.SequenceEqual(PemLabels.Pkcs8PrivateKey))
         {
             return(ImportPkcs8PrivateKey);
         }
         else if (label.SequenceEqual(PemLabels.RsaPublicKey))
         {
             return(ImportRSAPublicKey);
         }
         else if (label.SequenceEqual(PemLabels.SpkiPublicKey))
         {
             return(ImportSubjectPublicKeyInfo);
         }
         else
         {
             return(null);
         }
     });
 }
Пример #2
0
 /// <summary>
 /// Imports an RFC 7468 textually encoded key, replacing the keys for this object.
 /// </summary>
 /// <param name="input">The text of the PEM key to import.</param>
 /// <exception cref="ArgumentException">
 /// <para>
 ///   <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
 /// </para>
 /// <para>
 ///   -or-
 /// </para>
 /// <para>
 ///   <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
 /// </para>
 /// <para>
 ///     -or-
 /// </para>
 /// <para>
 ///   <paramref name="input"/> contains an encrypted PEM-encoded key.
 /// </para>
 /// </exception>
 /// <exception cref="NotImplementedException">
 ///   A derived type has not provided an implementation for <see cref="ImportPkcs8PrivateKey" />
 ///   or <see cref="ImportSubjectPublicKeyInfo" />.
 /// </exception>
 /// <remarks>
 ///   <para>
 ///   Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
 ///   are found, an exception is raised to prevent importing a key when
 ///   the key is ambiguous.
 ///   </para>
 ///   <para>
 ///   This method supports the following PEM labels:
 ///   <list type="bullet">
 ///     <item><description>PUBLIC KEY</description></item>
 ///     <item><description>PRIVATE KEY</description></item>
 ///   </list>
 ///   </para>
 ///   <para>
 ///   Types that override this method may support additional PEM labels.
 ///   </para>
 /// </remarks>
 public virtual void ImportFromPem(ReadOnlySpan <char> input)
 {
     PemKeyHelpers.ImportPem(input, label =>
                             label switch
     {
         PemLabels.Pkcs8PrivateKey => ImportPkcs8PrivateKey,
         PemLabels.SpkiPublicKey => ImportSubjectPublicKeyInfo,
         _ => null,
     });
Пример #3
0
        /// <summary>
        /// Exports the current key in the PKCS#1 RSAPrivateKey format, PEM encoded.
        /// </summary>
        /// <returns>A string containing the PEM-encoded PKCS#1 RSAPrivateKey.</returns>
        /// <exception cref="CryptographicException">
        /// The key could not be exported.
        /// </exception>
        /// <remarks>
        /// <p>
        ///   A PEM-encoded PKCS#1 RSAPrivateKey will begin with <c>-----BEGIN RSA PRIVATE KEY-----</c>
        ///   and end with <c>-----END RSA PRIVATE KEY-----</c>, with the base64 encoded DER
        ///   contents of the key between the PEM boundaries.
        /// </p>
        /// <p>
        ///   The PEM is encoded according to the IETF RFC 7468 &quot;strict&quot;
        ///   encoding rules.
        /// </p>
        /// </remarks>
        public unsafe string ExportRSAPrivateKeyPem()
        {
            byte[] exported = ExportRSAPrivateKey();

            // Fixed to prevent GC moves.
            fixed(byte *pExported = exported)
            {
                try
                {
                    return(PemKeyHelpers.CreatePemFromData(PemLabels.RsaPrivateKey, exported));
                }
                finally
                {
                    CryptographicOperations.ZeroMemory(exported);
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Exports the current key in the PKCS#8 EncryptedPrivateKeyInfo format
        /// with a char-based password, PEM encoded.
        /// </summary>
        /// <param name="password">
        /// The password to use when encrypting the key material.
        /// </param>
        /// <param name="pbeParameters">
        /// The password-based encryption (PBE) parameters to use when encrypting the key material.
        /// </param>
        /// <returns>A string containing the PEM-encoded PKCS#8 EncryptedPrivateKeyInfo.</returns>
        /// <exception cref="NotImplementedException">
        /// An implementation for <see cref="ExportEncryptedPkcs8PrivateKey(ReadOnlySpan{char}, PbeParameters)" /> or
        /// <see cref="TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan{char}, PbeParameters, Span{byte}, out int)" /> has not been provided.
        /// </exception>
        /// <exception cref="CryptographicException">
        /// The key could not be exported.
        /// </exception>
        /// <remarks>
        /// <p>
        ///   When <paramref name="pbeParameters" /> indicates an algorithm that
        ///   uses PBKDF2 (Password-Based Key Derivation Function 2), the password
        ///   is converted to bytes via the UTF-8 encoding.
        /// </p>
        /// <p>
        ///   A PEM-encoded PKCS#8 EncryptedPrivateKeyInfo will begin with
        ///  <c>-----BEGIN ENCRYPTED PRIVATE KEY-----</c> and end with
        ///  <c>-----END ENCRYPTED PRIVATE KEY-----</c>, with the base64 encoded DER
        ///   contents of the key between the PEM boundaries.
        /// </p>
        /// <p>
        ///   The PEM is encoded according to the IETF RFC 7468 &quot;strict&quot;
        ///   encoding rules.
        /// </p>
        /// </remarks>
        public unsafe string ExportEncryptedPkcs8PrivateKeyPem(ReadOnlySpan <char> password, PbeParameters pbeParameters)
        {
            byte[] exported = ExportEncryptedPkcs8PrivateKey(password, pbeParameters);

            // Fixed to prevent GC moves.
            fixed(byte *pExported = exported)
            {
                try
                {
                    return(PemKeyHelpers.CreatePemFromData(PemLabels.EncryptedPkcs8PrivateKey, exported));
                }
                finally
                {
                    CryptographicOperations.ZeroMemory(exported);
                }
            }
        }
Пример #5
0
 /// <summary>
 /// Imports an encrypted RFC 7468 PEM-encoded key, replacing the keys for this object.
 /// </summary>
 /// <param name="input">The PEM text of the encrypted key to import.</param>
 /// <param name="passwordBytes">
 /// The bytes to use as a password when decrypting the key material.
 /// </param>
 /// <exception cref="ArgumentException">
 ///   <para>
 ///     <paramref name="input"/> does not contain a PEM-encoded key with a recognized label.
 ///   </para>
 ///   <para>
 ///       -or-
 ///   </para>
 ///   <para>
 ///     <paramref name="input"/> contains multiple PEM-encoded keys with a recognized label.
 ///   </para>
 /// </exception>
 /// <exception cref="CryptographicException">
 ///   <para>
 ///   The password is incorrect.
 ///   </para>
 ///   <para>
 ///       -or-
 ///   </para>
 ///   <para>
 ///   The base-64 decoded contents of the PEM text from <paramref name="input" />
 ///   do not represent an ASN.1-BER-encoded PKCS#8 EncryptedPrivateKeyInfo structure.
 ///   </para>
 ///   <para>
 ///       -or-
 ///   </para>
 ///   <para>
 ///   The base-64 decoded contents of the PEM text from <paramref name="input" />
 ///   indicate the key is for an algorithm other than the algorithm
 ///   represented by this instance.
 ///   </para>
 ///   <para>
 ///       -or-
 ///   </para>
 ///   <para>
 ///   The base-64 decoded contents of the PEM text from <paramref name="input" />
 ///   represent the key in a format that is not supported.
 ///   </para>
 ///   <para>
 ///       -or-
 ///   </para>
 ///   <para>
 ///   The algorithm-specific key import failed.
 ///   </para>
 /// </exception>
 /// <exception cref="NotImplementedException">
 ///   A derived type has not provided an implementation for
 ///  <see cref="ImportEncryptedPkcs8PrivateKey(ReadOnlySpan{byte}, ReadOnlySpan{byte}, out int)" />.
 /// </exception>
 /// <remarks>
 ///   <para>
 ///   The password bytes are passed directly into the Key Derivation Function (KDF)
 ///   used by the algorithm indicated by <c>pbeParameters</c>. This enables compatibility
 ///   with other systems which use a text encoding other than UTF-8 when processing
 ///   passwords with PBKDF2 (Password-Based Key Derivation Function 2).
 ///   </para>
 ///   <para>
 ///   Unsupported or malformed PEM-encoded objects will be ignored. If multiple supported PEM labels
 ///   are found, an exception is thrown to prevent importing a key when
 ///   the key is ambiguous.
 ///   </para>
 ///   <para>This method supports the <c>ENCRYPTED PRIVATE KEY</c> PEM label.</para>
 ///   <para>
 ///   Types that override this method may support additional PEM labels.
 ///   </para>
 /// </remarks>
 public virtual void ImportFromEncryptedPem(ReadOnlySpan <char> input, ReadOnlySpan <byte> passwordBytes)
 {
     PemKeyHelpers.ImportEncryptedPem <byte>(input, passwordBytes, ImportEncryptedPkcs8PrivateKey);
 }
Пример #6
0
 /// <summary>
 /// Exports the public-key portion of the current key in the PKCS#1
 /// RSAPublicKey format, PEM encoded.
 /// </summary>
 /// <returns>A string containing the PEM-encoded PKCS#1 RSAPublicKey.</returns>
 /// <exception cref="CryptographicException">
 /// The key could not be exported.
 /// </exception>
 /// <remarks>
 /// <p>
 ///   A PEM-encoded PKCS#1 RSAPublicKey will begin with <c>-----BEGIN RSA PUBLIC KEY-----</c>
 ///   and end with <c>-----END RSA PUBLIC KEY-----</c>, with the base64 encoded DER
 ///   contents of the key between the PEM boundaries.
 /// </p>
 /// <p>
 ///   The PEM is encoded according to the IETF RFC 7468 &quot;strict&quot;
 ///   encoding rules.
 /// </p>
 /// </remarks>
 public string ExportRSAPublicKeyPem()
 {
     byte[] exported = ExportRSAPublicKey();
     return(PemKeyHelpers.CreatePemFromData(PemLabels.RsaPublicKey, exported));
 }
Пример #7
0
 /// <summary>
 /// Exports the public-key portion of the current key in the X.509
 /// SubjectPublicKeyInfo format, PEM encoded.
 /// </summary>
 /// <returns>A string containing the PEM-encoded X.509 SubjectPublicKeyInfo.</returns>
 /// <exception cref="NotImplementedException">
 /// An implementation for <see cref="ExportSubjectPublicKeyInfo" /> or
 /// <see cref="TryExportSubjectPublicKeyInfo" /> has not been provided.
 /// </exception>
 /// <exception cref="CryptographicException">
 /// The key could not be exported.
 /// </exception>
 /// <remarks>
 /// <p>
 ///   A PEM-encoded X.509 SubjectPublicKeyInfo will begin with
 ///  <c>-----BEGIN PUBLIC KEY-----</c> and end with
 ///  <c>-----END PUBLIC KEY-----</c>, with the base64 encoded DER
 ///   contents of the key between the PEM boundaries.
 /// </p>
 /// <p>
 ///   The PEM is encoded according to the IETF RFC 7468 &quot;strict&quot;
 ///   encoding rules.
 /// </p>
 /// </remarks>
 public string ExportSubjectPublicKeyInfoPem()
 {
     byte[] exported = ExportSubjectPublicKeyInfo();
     return(PemKeyHelpers.CreatePemFromData(PemLabels.SpkiPublicKey, exported));
 }