/// <summary>Extracts the binary data from a PEM file.</summary>
    internal static byte[] GetDERFromPEM(string sPEM)
    {
        UInt32 dwSkip, dwFlags;
        UInt32 dwBinarySize = 0;

        if (!RSACryptoServiceProviderExtension.CryptStringToBinary(sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_BASE64HEADER, null, ref dwBinarySize, out dwSkip, out dwFlags))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }

        byte[] decodedData = new byte[dwBinarySize];
        if (!RSACryptoServiceProviderExtension.CryptStringToBinary(sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_BASE64HEADER, decodedData, ref dwBinarySize, out dwSkip, out dwFlags))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        return(decodedData);
    }
    /// <summary>Converts DER binary format to a CAPI CRYPT_PRIVATE_KEY_INFO structure.</summary>
    internal static byte[] GetPrivateKeyDER(byte[] DERData)
    {
        byte[] data = null;
        UInt32 dwRSAPrivateKeyBlobSize = 0;
        IntPtr pRSAPrivateKeyBlob      = IntPtr.Zero;

        if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.PKCS_RSA_PRIVATE_KEY),
                                                                DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwRSAPrivateKeyBlobSize))
        {
            data = new byte[dwRSAPrivateKeyBlobSize];
            if (!RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.PKCS_RSA_PRIVATE_KEY),
                                                                     DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwRSAPrivateKeyBlobSize))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
        }
        else
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        return(data);
    }
    /// <summary>Converts DER binary format to a CAPI CERT_PUBLIC_KEY_INFO structure containing an RSA key.</summary>
    internal static byte[] GetRSAFromDER(byte[] DERData)
    {
        byte[] data      = null;
        byte[] publicKey = null;
        CERT_PUBLIC_KEY_INFO info;
        UInt32 dwCertPublicKeyInfoSize = 0;
        IntPtr pCertPublicKeyInfo      = IntPtr.Zero;

        if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO),
                                                                DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwCertPublicKeyInfoSize))
        {
            data = new byte[dwCertPublicKeyInfoSize];
            if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO),
                                                                    DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwCertPublicKeyInfoSize))
            {
                GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
                try
                {
                    info      = (CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(CERT_PUBLIC_KEY_INFO));
                    publicKey = new byte[info.PublicKey.cbData];
                    Marshal.Copy(info.PublicKey.pbData, publicKey, 0, publicKey.Length);
                }
                finally
                {
                    handle.Free();
                }
            }
            else
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
        }
        else
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        return(publicKey);
    }
    /// <summary>Returns a public key blob from an RSA public key.</summary>
    internal static byte[] GetPublicKeyBlobFromRSA(byte[] RSAData)
    {
        byte[] data = null;
        UInt32 dwCertPublicKeyBlobSize = 0;

        if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING,
                                                                new IntPtr((int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.NONE,
                                                                data, ref dwCertPublicKeyBlobSize))
        {
            data = new byte[dwCertPublicKeyBlobSize];
            if (!RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING,
                                                                     new IntPtr((int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.NONE,
                                                                     data, ref dwCertPublicKeyBlobSize))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
        }
        else
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        return(data);
    }
 /// <summary>Extension method which initializes an RSACryptoServiceProvider from a PEM private key string.</summary>
 public static void LoadPrivateKeyPEM(this RSACryptoServiceProvider provider, string sPEM)
 {
     byte[] DERData = RSACryptoServiceProviderExtension.GetDERFromPEM(sPEM);
     RSACryptoServiceProviderExtension.LoadPrivateKeyDER(provider, DERData);
 }
 /// <summary>Extension method which initializes an RSACryptoServiceProvider from a DER private key blob.</summary>
 public static void LoadPrivateKeyDER(this RSACryptoServiceProvider provider, byte[] DERData)
 {
     byte[] privateKeyBlob = RSACryptoServiceProviderExtension.GetPrivateKeyDER(DERData);
     provider.ImportCspBlob(privateKeyBlob);
 }
 /// <summary>Extension method which initializes an RSACryptoServiceProvider from a DER public key blob.</summary>
 public static void LoadPublicKeyDER(this RSACryptoServiceProvider provider, byte[] DERData)
 {
     byte[] RSAData       = RSACryptoServiceProviderExtension.GetRSAFromDER(DERData);
     byte[] publicKeyBlob = RSACryptoServiceProviderExtension.GetPublicKeyBlobFromRSA(RSAData);
     provider.ImportCspBlob(publicKeyBlob);
 }