title: Import a persistent key in to Windows key storage using CNG storage functions
body: <p>I'm trying to import a persistent RSA public key into the key storage. I read on the <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/bb427412(v=vs.85).aspx" rel="nofollow">CNG help page</a> that it's possible for private keys and I wonder if I can also apply is to public keys (specifically the BCRYPT_RSAPUBLIC_BLOB). I've tried with the following code, but in the import section, when I call NCryptSetProperty to set the public blob as a property, I get "Error 0x80090029" which is NTE Bad Data. Having trouble debugging why this function is failing.</p>
  
  <pre><code>NCRYPT_PROV_HANDLE providerHandle = NULL;
  NCRYPT_KEY_HANDLE keyHandle = NULL;
  NTSTATUS status = STATUS_UNSUCCESSFUL;
  PBYTE blob = NULL;
  DWORD blob_len = 0;
  
  ///////////////////Export Test (extract key from storage)///////////////////////////
  
  // Open handle to the Key Storage Provider
  if(FAILED(status = NCryptOpenStorageProvider(
      &amp;providerHandle,            //OUT: provider handle
      MS_KEY_STORAGE_PROVIDER,    //IN: Microsoft key storage provider
      0)))                        //IN: dwFlags (unused)
  {
      //report fail
  }
  
  // Open key in the Key Storage Provider
  if (FAILED(status = NCryptOpenKey(
      providerHandle,
      &amp;keyHandle,
      keyName.c_str(),
      0,
      0)))
  {
      //report fail
  }
  
  // (2 step key extraction process) 1. Get size of key
  if (FAILED(status = NCryptExportKey(
      keyHandle,              //IN: Handle of the key to export
      NULL,                   //IN(opt): key used to encrypt exported BLOB data   &lt;-- potentially an safer way for key extraction, encrypt it with a key during extraction (decrypt with NCryptDecrypt)
      BCRYPT_RSAPUBLIC_BLOB,  //IN: BLOB type (https://msdn.microsoft.com/en-us/library/windows/desktop/aa376263%28v=vs.85%29.aspx)
      NULL,                   //IN(opt): List of paramters for the key
      NULL,                   //OUT(opt): Output byte buffer
      0,                      //IN:  Size of the output buffer
      &amp;blob_len,              //OUT: Amount of bytes copied to the output buffer
      0)))                    //IN: Flag to modify function behaviour (0 means no flag set)
  {
      //report fail
  }
  
  // Allocate data blob to store key in
  blob = (PBYTE)malloc(blob_len); 
  if (NULL == blob) {
      //report fail
  }
  
  // (2 step key extraction process) 2. Get key and store in byte array (Extracted key is in form of BCRYPT_RSAKEY_BLOB)
  if (FAILED(status = NCryptExportKey(
      keyHandle,
      NULL,
      BCRYPT_RSAPUBLIC_BLOB,
      NULL,
      blob,
      blob_len,
      &amp;blob_len,
      0)))
  {
      //report fail
  }
  
  
  ///////////////Import Test (Store into storage)//////////////////////////////////////////////
  
  // Create a persisted key
  if(FAILED(status = NCryptCreatePersistedKey(
      providerHandle,             //IN: provider handle
      &amp;keyHandle,                 //OUT: Handle to key
      NCRYPT_RSA_ALGORITHM,       //IN: CNG Algorithm Identifiers. NCRYPT_RSA_ALGORITHM creates public key
      keyName.c_str(),            //IN: Key name. If NULL, the key does not persist 
      0,                          //IN: Key type
      NCRYPT_OVERWRITE_KEY_FLAG)))//IN: Behaviour: 0 - apply to current user only, NCRYPT_MACHINE_KEY_FLAG - apply to local comp only, NCRYPT_OVERWRITE_KEY_FLAG - overwrite existing key
  {
      //report fail
  }
  
  // Set the size of the key
  if(FAILED(status = NCryptSetProperty(
      keyHandle,                          //IN: Handle to key
      BCRYPT_RSAPUBLIC_BLOB,              //IN: CNG Algorithm Identifiers. BCRYPT_RSAPUBLIC_BLOB allows me to use set this blob as the new key's blob
      blob,                               //IN: Key name. If NULL, the key does not persist 
      blob_len,                           //IN: Key Length
      0)))                                //IN: Bahaviour: 0 - apply to current user only, NCRYPT_MACHINE_KEY_FLAG - apply to local comp only, NCRYPT_OVERWRITE_KEY_FLAG - overwrite existing key
  {
      //report fail &lt;&lt;-------------------------- Fail here
  }
  
  // Finalize key generation (Key is now usable, but uneditable) 
  if(FAILED(status = NCryptFinalizeKey(keyHandle, 0)))            {
      //report fail
  }
  ////////////////////////////////////////////////////////////////////////
  </code></pre>