How to implement NCryptImportKey method in C#?

SUBRAMANIAN Prabhakaran 1 Reputation point
2021-12-08T11:27:05.19+00:00

Hi Team,
I have implemented NCryptExportKey method using Microsoft Key Storage Provider.

https://learn.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptexportkey

I have tried NCryptImportKey method but it is not working.
Please find code below.
Please share me the code for both methods NCryptExportKey and NCryptImportKey

[DllImport("Ncrypt.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int NCryptExportKey(IntPtr hKey, IntPtr hExportKey, string pszBlobType, IntPtr pParameterList,
[Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbOutput, int cbOutput, [Out] out int pcbResult, int dwFlags);

[DllImport("Ncrypt.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int NCryptImportKey(IntPtr hKey, IntPtr hExportKey, string pszBlobType, IntPtr pParameterList,
[Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbOutput, int cbOutput, [Out] out int pcbResult, int dwFlags);

public static void ExportKey()
{
IntPtr CngProviderHandle = IntPtr.Zero;
IntPtr CapiKeyHandle = IntPtr.Zero;
string KeyName = "SampleStrongKey";
int BlobLength = 0;
int Policy = NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;

        int secStatus = NCryptOpenStorageProvider(out CngProviderHandle, MS_KEY_STORAGE_PROVIDER, 0);  
        if (secStatus == 0)  
        {  
            secStatus = NCryptCreatePersistedKey(  
              CngProviderHandle,  
              out CapiKeyHandle,  
              NCRYPT_RSA_ALGORITHM,  
              KeyName,  
              0,  
              NCRYPT_OVERWRITE_KEY_FLAG);  

            byte[] bytesPolicy = BitConverter.GetBytes(Policy);  
            secStatus = NCryptSetProperty(  
            CapiKeyHandle,  
            NCRYPT_EXPORT_POLICY_PROPERTY,  
            bytesPolicy,  
            bytesPolicy.Length,  
            NCRYPT_PERSIST_FLAG);  

            secStatus = NCryptFinalizeKey(CapiKeyHandle, 0);  

            secStatus = NCryptExportKey(  
                  CapiKeyHandle,  
                   IntPtr.Zero,  
                  LEGACY_RSAPRIVATE_BLOB,  
                  IntPtr.Zero,  
                  null,  
                  0,  
                  out BlobLength,  
                  0);  

            byte[] Blob = new byte[BlobLength];  
            secStatus = NCryptExportKey(  
                CapiKeyHandle,  
                IntPtr.Zero,  
                LEGACY_RSAPRIVATE_BLOB,  
                IntPtr.Zero,  
                Blob,  
                BlobLength,  
                out BlobLength,  
                0);  

            secStatus = NCryptFinalizeKey(CapiKeyHandle, 0);  
            if (CngProviderHandle != IntPtr.Zero)  
            {  
                NCryptFreeObject(CngProviderHandle);  
            }  
        }  
    }  

public static void ImportKey()
{
IntPtr CngProviderHandle = IntPtr.Zero;
IntPtr CapiKeyHandle = IntPtr.Zero;
string KeyName = "SampleStrongKey";
int BlobLength = 0;

        int secStatus = NCryptOpenStorageProvider(out CngProviderHandle, MS_KEY_STORAGE_PROVIDER, 0);  
        if (secStatus == 0)  
        {  
            secStatus = NCryptOpenKey(CngProviderHandle, out CapiKeyHandle, KeyName, 0, 0);  

            secStatus = NCryptImportKey(  
                  CapiKeyHandle,  
                   IntPtr.Zero,  
                  LEGACY_RSAPRIVATE_BLOB,  
                  IntPtr.Zero,  
                  null,  
                  0,  
                  out BlobLength,  
                  0);  

            byte[] Blob = new byte[BlobLength];  
            secStatus = NCryptImportKey(  
                CapiKeyHandle,  
                IntPtr.Zero,  
                LEGACY_RSAPRIVATE_BLOB,  
                IntPtr.Zero,  
                Blob,  
                BlobLength,  
                out BlobLength,  
                0);  

            secStatus = NCryptFinalizeKey(CapiKeyHandle, 0);  
            if (CngProviderHandle != IntPtr.Zero)  
            {  
                NCryptFreeObject(CngProviderHandle);  
            }  
        }  
    }  
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,431 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,321 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Castorix31 81,836 Reputation points
    2021-12-08T11:49:41.717+00:00

    Read the doc better...

    The signature is not exactly the same as NCryptExportKey and the second to last parameter is not an out parameter

            [DllImport("Ncrypt.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            public static extern int NCryptImportKey(IntPtr hProvider, IntPtr hImportKey, string pszBlobType, IntPtr pParameterList,
                [Out] out IntPtr phKey, [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbData, int cbData, int dwFlags);