public static RSA GetRSAPublicKey(this X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }

            if (!IsRSA(certificate))
            {
                return(null);
            }

            PublicKey      publicKey  = certificate.PublicKey;
            AsnEncodedData asn        = publicKey.EncodedKeyValue;
            IntPtr         structType = new IntPtr(CapiNative.CNG_RSA_PUBLIC_KEY_BLOB);

            SafeLocalAllocHandle cngBlobHandle;
            uint cngBlobLength;
            bool result = CapiNative.DecodeObject(structType, asn.RawData, out cngBlobHandle, out cngBlobLength);

            if (!result)
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            byte[] cngBlob = new byte[cngBlobLength];
            using (cngBlobHandle)
            {
                Marshal.Copy(cngBlobHandle.DangerousGetHandle(), cngBlob, 0, cngBlob.Length);
            }

            CngKey key = CngKey.Import(cngBlob, CngKeyBlobFormat.GenericPublicBlob);

            return(new RSACng(key));
        }
        public static DSA GetDSAPublicKey(this X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }

            if (!IsDSA(certificate))
            {
                return(null);
            }

            unsafe
            {
                DSAParameters dp = new DSAParameters();

                SafeLocalAllocHandle dssKeyLocalAlloc = null;
                try
                {
                    byte[] encodedPublicKey = certificate.PublicKey.EncodedKeyValue.RawData;
                    uint   cbDSSKey;
                    if (!CapiNative.DecodeObject((IntPtr)(CapiNative.X509_DSS_PUBLICKEY), encodedPublicKey, out dssKeyLocalAlloc, out cbDSSKey))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    if (cbDSSKey < Marshal.SizeOf(typeof(CapiNative.CRYPTOAPI_BLOB)))
                    {
                        throw new CryptographicException();
                    }

                    CapiNative.CRYPTOAPI_BLOB *pDssKeyBlob = (CapiNative.CRYPTOAPI_BLOB *)(dssKeyLocalAlloc.DangerousGetHandle());
                    dp.Y = ToBigEndianByteArray(*pDssKeyBlob);
                }
                finally
                {
                    if (dssKeyLocalAlloc != null)
                    {
                        dssKeyLocalAlloc.Dispose();
                        dssKeyLocalAlloc = null;
                    }
                }

                SafeLocalAllocHandle dssParametersLocalHandle = null;
                try
                {
                    byte[] encodedKeyAlgorithmParameters = certificate.GetKeyAlgorithmParameters();
                    uint   cbDSSParams;
                    if (!CapiNative.DecodeObject((IntPtr)(CapiNative.X509_DSS_PARAMETERS), encodedKeyAlgorithmParameters, out dssParametersLocalHandle, out cbDSSParams))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    if (cbDSSParams < Marshal.SizeOf(typeof(CapiNative.CERT_DSS_PARAMETERS)))
                    {
                        throw new CryptographicException();
                    }

                    CapiNative.CERT_DSS_PARAMETERS *pDssParameters = (CapiNative.CERT_DSS_PARAMETERS *)(dssParametersLocalHandle.DangerousGetHandle());
                    dp.P = ToBigEndianByteArray(pDssParameters->p);
                    dp.Q = ToBigEndianByteArray(pDssParameters->q);
                    dp.G = ToBigEndianByteArray(pDssParameters->g);
                }
                finally
                {
                    if (dssParametersLocalHandle != null)
                    {
                        dssParametersLocalHandle.Dispose();
                        dssParametersLocalHandle = null;
                    }
                }

                DSACng dsaCng = new DSACng();
                dsaCng.ImportParameters(dp);
                return(dsaCng);
            }
        }