P/Invoking CryptoAPI in .NET (VB.NET version)

Hi, welcome back,

This is a continuation of my previous post, P/Invoking CryptoAPI in .NET (C# version).

Here you have the most common P/Invoke CryptoAPI declarations I've successfully used in the past, but this time for VB.NET ( Note: I've included a couple of auxiliary functions which may be of help, too. CertContextFromCertSubject gets a certificate context from a certificate in MY/Personal certificate store, and RSACryptoServiceProviderFromCertContext creates an RSACryptoServiceProvider object from that certificate context. I don't have them in C#, but they should be easy to convert):

 

<SAMPLE>

 Imports System.Runtime.InteropServices
Imports System.Security.Cryptography
Imports System.ComponentModel

Public Class Crypto

#Region "CONSTS"

    ' #define BUFSIZE   1024
    Public Const BUFSIZE As Int32 = 1024

    ' #define AT_KEYEXCHANGE        1
    Public Const AT_KEYEXCHANGE As Int32 = 1

    ' #define AT_SIGNATURE      2
    Public Const AT_SIGNATURE As Int32 = 2

    ' #define CERT_STORE_PROV_SYSTEM_W      ((LPCSTR) 10)
    Public Const CERT_STORE_PROV_SYSTEM_W As Int32 = 10

    ' #define CERT_STORE_PROV_SYSTEM        CERT_STORE_PROV_SYSTEM_W
    Public Const CERT_STORE_PROV_SYSTEM As Int32 = CERT_STORE_PROV_SYSTEM_W

    ' #define CERT_SYSTEM_STORE_CURRENT_USER_ID     1
    Public Const CERT_SYSTEM_STORE_CURRENT_USER_ID As Int32 = 1

    ' #define CERT_SYSTEM_STORE_LOCATION_SHIFT      16
    Public Const CERT_SYSTEM_STORE_LOCATION_SHIFT As Int32 = 16

    ' #define CERT_SYSTEM_STORE_CURRENT_USER        \
    '   (CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT)
    Public Const CERT_SYSTEM_STORE_CURRENT_USER As Int32 = _
        CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT

    ' #define CERT_PERSONAL_STORE_NAME      L"My"
    Public Const CERT_PERSONAL_STORE_NAME As String = "My"

    ' #define X509_ASN_ENCODING     0x00000001
    Public Const X509_ASN_ENCODING As Int32 = &H1

    ' #define PKCS_7_ASN_ENCODING       0x00010000
    Public Const PKCS_7_ASN_ENCODING As Int32 = &H10000

    ' #define MY_TYPE       (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
    Public Const MY_TYPE As Int32 = PKCS_7_ASN_ENCODING + X509_ASN_ENCODING

    ' #define CERT_COMPARE_ANY      0
    Public Const CERT_COMPARE_ANY As Int32 = 0

    ' #define CERT_COMPARE_SHA1_HASH        1
    Public Const CERT_COMPARE_SHA1_HASH As Int32 = 1

    ' #define CERT_COMPARE_SHIFT        16
    Public Const CERT_COMPARE_SHIFT As Int32 = 16

    ' #define CERT_FIND_SHA1_HASH       (CERT_COMPARE_SHA1_HASH << CERT_COMPARE_SHIFT)
    Public Const CERT_FIND_SHA1_HASH As Int32 = CERT_COMPARE_SHA1_HASH << CERT_COMPARE_SHIFT

    ' #define CERT_FIND_HASH        CERT_FIND_SHA1_HASH
    Public Const CERT_FIND_HASH As Int32 = CERT_FIND_SHA1_HASH

    ' #define CERT_FIND_ANY     (CERT_COMPARE_ANY << CERT_COMPARE_SHIFT)
    Public Const CERT_FIND_ANY As Int32 = CERT_COMPARE_ANY << CERT_COMPARE_SHIFT

    ' #define CERT_COMPARE_NAME   2
    Public Const CERT_COMPARE_NAME As Int32 = 2

    ' #define CERT_INFO_SUBJECT_FLAG  7
    Public Const CERT_INFO_SUBJECT_FLAG As Int32 = 7

    ' #define CERT_FIND_SUBJECT_NAME    (CERT_COMPARE_NAME << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
    Public Const CERT_FIND_SUBJECT_NAME As Int32 = (CERT_COMPARE_NAME << CERT_COMPARE_SHIFT) + CERT_INFO_SUBJECT_FLAG

    ' #define CERT_COMPARE_NAME_STR_W     8
    Public Const CERT_COMPARE_NAME_STR_W As Int32 = 8

    ' #define CERT_FIND_SUBJECT_STR_W   \
    '   (CERT_COMPARE_NAME_STR_W << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
    Public Const CERT_FIND_SUBJECT_STR_W As Int32 = (CERT_COMPARE_NAME_STR_W << CERT_COMPARE_SHIFT) + CERT_INFO_SUBJECT_FLAG

    ' #define CERT_FIND_SUBJECT_STR CERT_FIND_SUBJECT_STR_W
    Public Const CERT_FIND_SUBJECT_STR As Int32 = CERT_FIND_SUBJECT_STR_W

    ' #define CERT_CLOSE_STORE_CHECK_FLAG       0x00000002
    Public Const CERT_CLOSE_STORE_CHECK_FLAG As Int32 = &H2

    ' #define ALG_CLASS_HASH        (4 << 13)
    Public Const ALG_CLASS_HASH As Int32 = 4 << 13

    ' #define ALG_TYPE_ANY      (0)
    Public Const ALG_TYPE_ANY As Int32 = 0

    ' #define ALG_SID_MD5       3
    Public Const ALG_SID_MD5 As Int32 = 3

    ' #define ALG_SID_SHA1      4
    Public Const ALG_SID_SHA1 As Int32 = 4

    ' #define CALG_MD5      (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5)
    Public Const CALG_MD5 As Int32 = ALG_CLASS_HASH + ALG_TYPE_ANY + ALG_SID_MD5

    ' #define CALG_SHA1     (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA1)
    Public Const CALG_SHA1 As Int32 = ALG_CLASS_HASH + ALG_TYPE_ANY + ALG_SID_SHA1

    ' #define PP_KEYEXCHANGE_PIN        32
    Public Const PP_KEYEXCHANGE_PIN As Int32 = 32

    ' #define PP_SIGNATURE_PIN      33
    Public Const PP_SIGNATURE_PIN As Int32 = 33

    ' #define PROV_RSA_FULL     1
    Public Const PROV_RSA_FULL As Int32 = &H1

    ' #define CRYPT_VERIFYCONTEXT       0xF0000000
    Public Const CRYPT_VERIFYCONTEXT As Int32 = &HF0000000

    ' #define CERT_KEY_PROV_INFO_PROP_ID    2
    Public Const CERT_KEY_PROV_INFO_PROP_ID As Int32 = 2

#End Region

#Region "STRUCTS"

    ' typedef struct _CRYPTOAPI_BLOB {
    '   DWORD   cbData;
    '   BYTE    *pbData;
    ' } CRYPT_HASH_BLOB, CRYPT_INTEGER_BLOB, 
    '   CRYPT_OBJID_BLOB, CERT_NAME_BLOB;
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure CRYPTOAPI_BLOB
        Public cbData As Int32
        Public pbData As IntPtr
    End Structure

    ' typedef struct _CRYPT_ALGORITHM_IDENTIFIER {
    '   LPSTR               pszObjId;
    '   CRYPT_OBJID_BLOB    Parameters;
    ' } CRYPT_ALGORITHM_IDENTIFIER;
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure CRYPT_ALGORITHM_IDENTIFIER
        <MarshalAs(UnmanagedType.LPStr)> Public pszObjId As String
        Public Parameters As CRYPTOAPI_BLOB
    End Structure

    ' typedef struct _FILETIME {
    '   DWORD dwLowDateTime;
    '   DWORD dwHighDateTime;
    ' } FILETIME;
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure FILETIME
        Public dwLowDateTime As Int32
        Public dwHighDateTime As Int32
    End Structure

    ' typedef struct _CRYPT_BIT_BLOB {
    '   DWORD   cbData;
    '   BYTE    *pbData;
    '   DWORD   cUnusedBits;
    ' } CRYPT_BIT_BLOB;
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure CRYPT_BIT_BLOB
        Public cbData As Int32
        Public pbData As Byte()
        Public cUnusedBits As Int32
    End Structure

    ' typedef struct _CERT_PUBLIC_KEY_INFO {
    '   CRYPT_ALGORITHM_IDENTIFIER    Algorithm;
    '   CRYPT_BIT_BLOB                PublicKey;
    ' } CERT_PUBLIC_KEY_INFO;
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure CERT_PUBLIC_KEY_INFO
        Public Algorithm As CRYPT_ALGORITHM_IDENTIFIER
        Public PublicKey As CRYPT_BIT_BLOB
    End Structure

    ' typedef struct _CERT_INFO {
    '   DWORD                       dwVersion;
    '   CRYPT_INTEGER_BLOB          SerialNumber;
    '   CRYPT_ALGORITHM_IDENTIFIER  SignatureAlgorithm;
    '   CERT_NAME_BLOB              Issuer;
    '   FILETIME                    NotBefore;
    '   FILETIME                    NotAfter;
    '   CERT_NAME_BLOB              Subject;
    '   CERT_PUBLIC_KEY_INFO        SubjectPublicKeyInfo;
    '   CRYPT_BIT_BLOB              IssuerUniqueId;
    '   CRYPT_BIT_BLOB              SubjectUniqueId;
    '   DWORD                       cExtension;
    '   PCERT_EXTENSION             rgExtension;
    ' } CERT_INFO;
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure CERT_INFO
        Public dwVersion As Int32
        Public SerialNumber As CRYPTOAPI_BLOB
        Public SignatureAlgorithm As CRYPT_ALGORITHM_IDENTIFIER
        Public Issuer As CRYPTOAPI_BLOB
        Public NotBefore As FILETIME
        Public NotAfter As FILETIME
        Public Subject As CRYPTOAPI_BLOB
        Public SubjectPublicKeyInfo As CERT_PUBLIC_KEY_INFO
        Public IssuerUniqueId As CRYPT_BIT_BLOB
        Public SubjectUniqueId As CRYPT_BIT_BLOB
        Public cExtension As Int32
        Public rgExtension As IntPtr
    End Structure

    ' typedef struct _CERT_CONTEXT {
    '   DWORD                   dwCertEncodingType;
    '   BYTE                    *pbCertEncoded;
    '   DWORD                   cbCertEncoded;
    '   PCERT_INFO              pCertInfo;
    '   HCERTSTORE              hCertStore;
    ' } CERT_CONTEXT;
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure CERT_CONTEXT
        Public dwCertEncodingType As Int32
        Public pbCertEncoded As Byte()
        Public cbCertEncoded As Int32
        Public pCertInfo As IntPtr
        Public hCertStore As IntPtr
    End Structure

#End Region

#Region "FUNCTIONS (IMPORTS)"

    ' HCERTSTORE WINAPI CertOpenStore(
    '   LPCSTR lpszStoreProvider,
    '   DWORD dwMsgAndCertEncodingType,
    '   HCRYPTPROV hCryptProv,
    '   DWORD dwFlags,
    '   const void* pvPara
    ' );
    <DllImport("Crypt32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Public Shared Function CertOpenStore( _
        ByVal lpszStoreProvider As Int32, _
        ByVal dwMsgAndCertEncodingType As Int32, _
        ByVal hCryptProv As IntPtr, _
        ByVal dwFlags As Int32, _
        ByVal pvPara As String _
    ) As IntPtr
    End Function

    ' HCERTSTORE WINAPI CertOpenSystemStore(
    '   HCRYPTPROV hprov,
    '   LPTCSTR szSubsystemProtocol
    ');
    <DllImport("Crypt32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Public Shared Function CertOpenSystemStore( _
        ByVal hprov As IntPtr, _
        ByVal szSubsystemProtocol As String _
    ) As IntPtr
    End Function

    ' PCCERT_CONTEXT WINAPI CertFindCertificateInStore(
    '   HCERTSTORE hCertStore,
    '   DWORD dwCertEncodingType,
    '   DWORD dwFindFlags,
    '   DWORD dwFindType,
    '   const void* pvFindPara,
    '   PCCERT_CONTEXT pPrevCertContext
    ' );
    '<DllImport("Crypt32.dll", SetLastError:=True)> _
    'Public Shared Function CertFindCertificateInStore( _
    '    ByVal hCertStore As IntPtr, _
    '    ByVal dwCertEncodingType As Int32, _
    '    ByVal dwFindFlags As Int32, _
    '    ByVal dwFindType As Int32, _
    '    ByRef pvFindPara As CRYPTOAPI_BLOB, _
    '    ByVal pPrevCertContext As IntPtr _
    ') As IntPtr
    'End Function
    <DllImport("Crypt32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Public Shared Function CertFindCertificateInStore( _
        ByVal hCertStore As IntPtr, _
        ByVal dwCertEncodingType As Int32, _
        ByVal dwFindFlags As Int32, _
        ByVal dwFindType As Int32, _
        ByVal pvFindPara As String, _
        ByVal pPrevCertContext As IntPtr _
    ) As IntPtr
    End Function

    ' BOOL WINAPI CryptAcquireCertificatePrivateKey(
    '   PCCERT_CONTEXT pCert,
    '   DWORD dwFlags,
    '   void* pvReserved,
    '   HCRYPTPROV* phCryptProv,
    '   DWORD* pdwKeySpec,
    '   BOOL* pfCallerFreeProv
    ' );
    <DllImport("Crypt32.dll", SetLastError:=True)> _
    Public Shared Function CryptAcquireCertificatePrivateKey( _
        ByVal pCert As IntPtr, _
        ByVal dwFlags As Int32, _
        ByVal pvReserverd As IntPtr, _
        ByRef phCryptProv As IntPtr, _
        ByRef pdwKeySpec As Int32, _
        ByRef pfCallerFreeProv As Boolean _
    ) As Boolean
    End Function

    ' BOOL WINAPI CertCloseStore(
    '   HCERTSTORE hCertStore,
    '   DWORD dwFlags
    ' );
    <DllImport("Crypt32.dll", SetLastError:=True)> _
    Public Shared Function CertCloseStore( _
        ByVal hCertStore As IntPtr, _
        ByVal dwFlags As Int32 _
    ) As Boolean
    End Function

    ' BOOL WINAPI CryptReleaseContext(
    '   HCRYPTPROV hProv,
    '   DWORD dwFlags
    ' );
    <DllImport("Advapi32.dll", SetLastError:=True)> _
    Public Shared Function CryptReleaseContext( _
        ByVal hProv As IntPtr, _
        ByVal dwFlags As Int32 _
    ) As Boolean
    End Function

    ' BOOL WINAPI CryptCreateHash(
    '   HCRYPTPROV hProv,
    '   ALG_ID Algid,
    '   HCRYPTKEY hKey,
    '   DWORD dwFlags,
    '   HCRYPTHASH* phHash
    ' );
    <DllImport("advapi32.dll", SetLastError:=True)> _
    Public Shared Function CryptCreateHash( _
        ByVal hProv As IntPtr, _
        ByVal Algid As Int32, _
        ByVal hKey As IntPtr, _
        ByVal dwFlags As Int32, _
        ByRef phHash As IntPtr _
    ) As Boolean
    End Function

    ' BOOL WINAPI CryptDestroyHash(
    '   HCRYPTHASH hHash
    ' );
    <DllImport("advapi32.dll", SetLastError:=True)> _
    Public Shared Function CryptDestroyHash( _
        ByVal hHash As IntPtr _
    ) As Boolean
    End Function

    ' BOOL WINAPI CryptSetProvParam(
    '   HCRYPTPROV hProv,
    '   DWORD dwParam,
    '   BYTE* pbData,
    '   DWORD dwFlags
    ' );
    <DllImport("advapi32.dll", SetLastError:=True)> _
    Public Shared Function CryptSetProvParam( _
        ByVal hProv As IntPtr, _
        ByVal dwParam As Int32, _
        ByVal pbData As Byte(), _
        ByVal dwFlags As Int32 _
    ) As Boolean
    End Function

    ' BOOL WINAPI CryptHashData(
    '   HCRYPTHASH hHash,
    '   BYTE* pbData,
    '   DWORD dwDataLen,
    '   DWORD dwFlags
    ' ); 
    <DllImport("advapi32.dll", SetLastError:=True)> _
    Public Shared Function CryptHashData( _
        ByVal hHash As IntPtr, _
        ByVal pbData As Byte(), _
        ByVal dwDataLen As Int32, _
        ByVal dwFlags As Int32 _
    ) As Boolean
    End Function

    ' BOOL WINAPI CryptSignHash(
    '   HCRYPTHASH hHash,
    '   DWORD dwKeySpec,
    '   LPCTSTR sDescription,
    '   DWORD dwFlags,
    '   BYTE* pbSignature,
    '   DWORD* pdwSigLen
    ' );
    <DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Public Shared Function CryptSignHash( _
        ByVal hHash As IntPtr, _
        ByVal dwKeySpec As Int32, _
        ByVal sDescription As String, _
        ByVal dwFlags As Int32, _
        ByVal pbSignature As Byte(), _
        ByRef pdwSigLen As Int32 _
    ) As Boolean
    End Function

    ' BOOL WINAPI CertFreeCertificateContext(
    '   PCCERT_CONTEXT pCertContext
    ' );
    <DllImport("Crypt32.dll", SetLastError:=True)> _
    Public Shared Function CertFreeCertificateContext( _
        ByVal pCertContext As IntPtr _
    ) As Boolean
    End Function

    ' BOOL WINAPI CryptAcquireContext(
    '   HCRYPTPROV* phProv,
    '   LPCTSTR pszContainer,
    '   LPCTSTR pszProvider,
    '   DWORD dwProvType,
    '   DWORD dwFlags
    ' );
    <DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Public Shared Function CryptAcquireContext( _
        ByRef hProv As IntPtr, _
        ByVal pszContainer As String, _
        ByVal pszProvider As String, _
        ByVal dwProvType As Int32, _
        ByVal dwFlags As Int32 _
    ) As Boolean
    End Function

    ' BOOL WINAPI CryptImportPublicKeyInfo(
    '   HCRYPTPROV hCryptProv,
    '   DWORD dwCertEncodingType,
    '   PCERT_PUBLIC_KEY_INFO pInfo,
    '   HCRYPTKEY* phKey
    ' );
    <DllImport("crypt32.dll", SetLastError:=True)> _
    Public Shared Function CryptImportPublicKeyInfo( _
        ByVal hCryptProv As IntPtr, _
        ByVal dwCertEncodingType As Int32, _
        ByVal pInfo As IntPtr, _
        ByRef phKey As IntPtr _
    ) As Boolean
    End Function

    ' BOOL WINAPI CryptVerifySignature(
    '   HCRYPTHASH hHash,
    '   BYTE* pbSignature,
    '   DWORD dwSigLen,
    '   HCRYPTKEY hPubKey,
    '   LPCTSTR sDescription,
    '   DWORD dwFlags
    ' );
    <DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Public Shared Function CryptVerifySignature( _
        ByVal hHash As IntPtr, _
        ByVal pbSignature As Byte(), _
        ByVal dwSigLen As Int32, _
        ByVal hPubKey As IntPtr, _
        ByVal sDescription As String, _
        ByVal dwFlags As Int32 _
    ) As Boolean
    End Function

    ' BOOL WINAPI CryptDestroyKey(
    '   HCRYPTKEY hKey
    ' );
    <DllImport("advapi32.dll", SetLastError:=True)> _
    Public Shared Function CryptDestroyKey( _
        ByVal hKey As IntPtr _
    ) As Boolean
    End Function

    ' BOOL WINAPI CertGetCertificateContextProperty(
    '   PCCERT_CONTEXT pCertContext,
    '   DWORD dwPropId,
    '   void* pvData,
    '   DWORD* pcbData
    ' );
    <DllImport("crypt32.dll", SetLastError:=True)> _
    Public Shared Function CertGetCertificateContextProperty( _
        ByVal pCertContext As IntPtr, _
        ByVal dwPropId As Int32, _
        ByVal pvData As IntPtr, _
        ByRef pcbData As Int32 _
    ) As Boolean
    End Function

    ' PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(
    '   HCERTSTORE hCertStore,
    '   PCCERT_CONTEXT pPrevCertContext
    ');
    <DllImport("crypt32.dll", SetLastError:=True)> _
    Public Shared Function CertEnumCertificatesInStore( _
        ByVal hCertStore As IntPtr, _
        ByVal pPrevCertContext As IntPtr _
    ) As IntPtr
    End Function

    ' PCCERT_CONTEXT WINAPI CertDuplicateCertificateContext(
    '   PCCERT_CONTEXT pCertContext
    ');
    <DllImport("crypt32.dll", SetLastError:=True)> _
    Public Shared Function CertDuplicateCertificateContext( _
        ByVal pCertContext As IntPtr _
    ) As IntPtr
    End Function

#End Region

#Region "FUNCTIONS"

    Public Shared Function CertContextFromCertSubject(ByVal subject As String) As IntPtr

        ' Variables
        '
        Dim bResult As Boolean = False
        Dim hStoreHandle As IntPtr = IntPtr.Zero
        Dim pCertContext As IntPtr = IntPtr.Zero

        Try

            ' Open the certificate store.
            '
            hStoreHandle = CertOpenSystemStore( _
                0, _
                CERT_PERSONAL_STORE_NAME _
            )
            If (hStoreHandle.Equals(IntPtr.Zero)) Then
                Throw New Exception("CertOpenStore error", New Win32Exception(Marshal.GetLastWin32Error()))
            End If

            ' Get a certificate that matches the search criteria.
            ' 
            pCertContext = CertFindCertificateInStore( _
                hStoreHandle, _
                MY_TYPE, _
                0, _
                CERT_FIND_SUBJECT_STR, _
                subject, _
                IntPtr.Zero _
            )
            If (pCertContext.Equals(IntPtr.Zero)) Then
                Throw New Exception("CertFindCertificateInStore error", New Win32Exception(Marshal.GetLastWin32Error()))
            End If

            Return pCertContext

        Catch ex As Exception

            ' Any errors? Show them.
            '
            If (ex.InnerException Is Nothing) Then
                MessageBox.Show(ex.Message)
            Else
                MessageBox.Show(ex.Message + " --> " + ex.InnerException.Message)
            End If

        Finally

            ' Clean up and free memory.
            '
            If (Not hStoreHandle.Equals(IntPtr.Zero)) Then
                bResult = CertCloseStore( _
                    hStoreHandle, _
                    CERT_CLOSE_STORE_CHECK_FLAG _
                )
            End If

        End Try

        Return Nothing

    End Function

    ' Converted to VB.NET from KB article 320602
    '
    Public Shared Function RSACryptoServiceProviderFromCertContext(ByVal pCertContext As IntPtr) As RSACryptoServiceProvider

        'Determine the size of the buffer that you need to allocate.
        '
        Dim cbData As Int32 = 0
        Dim fStatus As Boolean = CertGetCertificateContextProperty( _
            pCertContext, _
            CERT_KEY_PROV_INFO_PROP_ID, _
            0, _
            cbData)

        If (Not fStatus) Then
            MessageBox.Show("CertGetCertificateContextProperty error --> " + Marshal.GetLastWin32Error().ToString())

            ' Get the CERT_KEY_PROV_HANDLE_PROP_ID value and the HCRYPTPROV value.
            '
            cbData = 4
            Dim pCryptKeyProvInfo As IntPtr = Marshal.AllocHGlobal(New IntPtr(cbData))
            fStatus = CertGetCertificateContextProperty( _
                pCertContext, _
                CERT_KEY_PROV_INFO_PROP_ID, _
                pCryptKeyProvInfo, _
                cbData)

            If (Not fStatus) Then
                MessageBox.Show("CertGetCertificateContextProperty error --> " + Marshal.GetLastWin32Error().ToString())
            End If
            Return Nothing

        End If

        If (Not cbData = 0) Then

            ' Allocate an unmanaged buffer to store the CRYPT_KEY_PROV_INFO structure.
            '
            Dim pCryptKeyProvInfo As IntPtr = Marshal.AllocHGlobal(cbData)

            ' Get the CRYPT_KEY_PROV_INFO structure.
            '
            fStatus = CertGetCertificateContextProperty( _
                pCertContext, _
                CERT_KEY_PROV_INFO_PROP_ID, _
                pCryptKeyProvInfo, _
                cbData)

            If (Not fStatus) Then
                MessageBox.Show("CertGetCertificateContextProperty failed: " + Marshal.GetLastWin32Error().ToString())
                Marshal.FreeHGlobal(pCryptKeyProvInfo)
            Else

                ' Build a CspParameters object with the provider type, the provider name,
                ' and the container name from the CRYPT_KEY_PROV_INFO structure.
                ' The pointer to the container name is the first DWORD in the CRYPT_KEY_PROV_INFO
                ' structure, the pointer to the provider name is the second DWORD, and
                ' the provider type is the third DWORD.
                '
                Try
                    Dim CspParams As CspParameters = New CspParameters( _
                        Marshal.ReadInt32(New IntPtr(pCryptKeyProvInfo.ToInt32 + 8)), _
                        Marshal.PtrToStringUni(New IntPtr(Marshal.ReadInt32(New IntPtr(pCryptKeyProvInfo.ToInt32 + 4)))), _
                        Marshal.PtrToStringUni(New IntPtr(Marshal.ReadInt32(pCryptKeyProvInfo))))

                    ' Free the unmanaged CRYPT_KEY_PROV_INFO buffer.
                    '
                    Marshal.FreeHGlobal(pCryptKeyProvInfo)
                    Return New RSACryptoServiceProvider(CspParams)

                Catch ex As Exception
                    MessageBox.Show(ex.Message)
                End Try

            End If
        End If
        Return Nothing

    End Function

#End Region

End Class

</SAMPLE>

 

I hope this helps.

Cheers,

 

Alex (Alejandro Campos Magencio)