Operaciones relacionadas con la clave de GNC

Directorio de capítulos

  1. Introduccion
  2. Crear clave
  3. Ver la clave en el sistema
  4. Exportar clave de la Tienda Windows
  5. Importar clave a la tienda de Windows

<b> La capacidad del autor es limitada. Si encuentra algún error durante el proceso de lectura, comuníquese conmigo para señalar los errores y evitar que los lectores aprendan el conocimiento incorrecto más tarde. ¡Gracias! </ b>

Introduccion

CNG significa Cryptography API: Next Generation (CNG). Es el término general para las API relacionadas con el cifrado de próxima generación en la plataforma Windows. Es una alternativa a Crypto API. En comparación con CryptoAPI, tiene funciones más potentes.

Este artículo proporcionará un método para usar CNG para operar la clave y las API relacionadas en forma de ejemplos.

Tenga en cuenta que en este artículo usamos la clave RSA como ejemplo, las claves DSA y ECC también son aplicables.

Crear clave

La versión actual de CNG admite algoritmos RSA, DSA y ECC. Aquí creamos una clave RSA con una longitud de clave de 2048 bits. Tenga en cuenta que cuando intente crear una clave DSA 2048, asegúrese de que su sistema lo admita. My Win7 es No es compatible, y Win10 es compatible (prueba profesional).

Aquí usamos las siguientes API en secuencia:
<code> NCryptOpenStorageProvider </ code> Este método se utiliza para cargar e inicializar un proveedor de almacenamiento de claves CNG existente. Dos KSP se integran en el sistema Windows actual: MS_KEY_STORAGE_PROVIDER, MS_SMART_CARD_KEY_STORAGE_PROVIDER_PROVIDER_. .
<code> NCryptCreatePersistedKey </ code> Este método se utiliza para la clave de un algoritmo específico y lo almacena en el KSP especificado. Tenga en cuenta que la clave creada por este método se almacenará en el sistema de Windows como un archivo.
<code> NCryptSetProperty </ code> Este método se utiliza para establecer la propiedad de la clave. En el ejemplo, lo usaremos para establecer la longitud de la clave en 2048 bits.
<code> NCryptFinalizeKey </ code> Este método se utiliza para notificar a Windows que la operación de creación de la clave se ha completado, llame a Después de este método, la Clave que creamos puede usarse para operaciones como el cifrado de firma, de lo contrario no puede.
<Code> NCryptFreeObject </ code> Este método se usa para liberar el identificador del sistema que utilizamos en la operación anterior.

int Create2048RSAKey() {
  int errCode = 0;

  NCRYPT_PROV_HANDLE prov = NULL;
  NCRYPT_KEY_HANDLE  key = NULL;
  DWORD keyLength = 2048;
  DWORD policy = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;

  if (errCode = NCryptOpenStorageProvider(&prov, MS_KEY_STORAGE_PROVIDER, 0)) goto done;
  if (errCode = NCryptCreatePersistedKey(prov, &key, NCRYPT_RSA_ALGORITHM, L"TestRSAKey", 0, NCRYPT_OVERWRITE_KEY_FLAG)) goto done;
  if (errCode = NCryptSetProperty(key, NCRYPT_LENGTH_PROPERTY, (PBYTE)(&keyLength), sizeof(keyLength), NCRYPT_PERSIST_FLAG)) goto done;
  if (errCode = NCryptSetProperty(key, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)(&policy), sizeof(policy), NCRYPT_PERSIST_FLAG)) goto done;
  if (errCode = NCryptFinalizeKey(key, 0)) goto done;

done:
  if (prov) NCryptFreeObject(prov);
  if (key) NCryptFreeObject(key);
  return errCode;
}

Después de ejecutar este método en su computadora con Windows, la clave que acabamos de crear se almacenará en su sistema. En la
siguiente sección, utilizaremos la API CNG para ver la información de la clave que creamos.

Ver la clave en el sistema

La API de CNG que usaremos aquí es:
<code> NCryptEnumKeys </ code> Este método se utiliza para recorrer todas las claves almacenadas en el KSP actual.
Aquí explicamos algunos de sus parámetros:
<code> NCryptKeyName ** ppKeyName </ code> Este parámetro se usa como el valor de retorno del método, que guarda el nombre de la clave actual, el algoritmo de la clave y otra información importante. El nombre es particularmente importante, por ejemplo, en nuestro ejemplo, usaremos el nombre para obtener el identificador de la clave, y luego usaremos la clave para hacer Más operaciones.
<Code> PVOID * ppEnumState </ code> Este parámetro también se usa como el valor de retorno del método. Pero su valor no tiene sentido para la persona que llama. Almacena la información intermedia de la clave transversal, que somos nosotros La próxima vez que se llame al parámetro de entrada del método NCryptEnumKeys. Si este parámetro se establece en NULL, el recorrido siempre devolverá la información de la primera clave del KSP actual.
<Código> valor de retorno </ código> Cuando este método devuelve un valor de NTE_NO_MORE_ITEMS, representa Ha atravesado todas las claves en el KSP actual.
<Código> NCryptOpenKey </ code> Este método se utiliza para obtener el controlador de clave que ejecuta el nombre especificado en el KSP.
<Código> NCryptGetProperty </ code> Este método se utiliza Se usa para obtener las propiedades de Key.

int ListKeys() {
  int errCode = 0;
  NCRYPT_PROV_HANDLE prov        = NULL;
  NCRYPT_KEY_HANDLE  key         = NULL;
  NCryptKeyName*     pKeyName    = NULL;
  PVOID              pEnumState = NULL;
  
  if (errCode = NCryptOpenStorageProvider(&prov, MS_KEY_STORAGE_PROVIDER, 0)) goto done;
  do {
    errCode = NCryptEnumKeys(prov, 0, &pKeyName, &pEnumState, 0);
    if (errCode == NTE_NO_MORE_ITEMS) break; // all the keys are enumerated
    if (!pKeyName) break; // should not happen
    
    LPCWSTR name = pKeyName->pszName;
    LPCWSTR alg  = pKeyName->pszAlgid;
    
    // get key length property
    DWORD keyLength = 0,  outLen = 0;
    if (errCode = NCryptOpenKey(prov, &key, name, 0, 0)) goto done;
    if (errCode = NCryptGetProperty(key, NCRYPT_LENGTH_PROPERTY, (PBYTE) (&keyLength), sizeof(keyLength), &outLen, 0)) goto done;

    wprintf(L"KeyName: %s, KeyAlgorithm: %s, KeyLength: %d", name, alg, keyLength);
  } while (!errCode);
  
done:
  if (prov) NCryptFreeObject(prov);
  if (key) NCryptFreeObject(key);
  return errCode;
}

Si ejecuta la función en la primera sección en su computadora y luego ejecuta la función ListKeys, su línea de comando definitivamente contendrá esta salida:

<code> KeyName: TestRSAKey, KeyAlgorithm: RSA, KeyLength: 2048 </code>

Exportar clave de la Tienda Windows

A través de la descripción de las dos subsecciones anteriores, hemos creado con éxito la Clave en el sistema de Windows, y podemos ver la información de la Clave para obtener el identificador de la Clave. Utilizando el Clave de la Clave podemos completar mucho trabajo. Sin embargo, muchas veces necesitamos colocar la Clave en todas partes Al archivo y compártelo con sus compañeros.

En esta sección, intentaremos exportar la clave.

<code> NCryptExportKey </ code> Este método se utiliza para exportar la clave del sistema al blob de memoria.
Tiene un parámetro muy importante:
<code> LPCWSTR pszBlobType </ code> se utiliza para controlar el formato del blob de memoria exportado. En el ejemplo, usamos NCRYPT_PKCS8_PRIVATE_KEY_BLOB. <B> Créame, este formato será el más conveniente para que procesemos más. Otros formatos, como BCRYPT_DSA_PUBLIC_BLOB, LEGACY_DSA_PRIVATE_BLOB, etc. se ven muy amigables, pero no siempre son muy amigables. Funciona así. Su formato no siempre es el mismo que cuando se exporta CryptExportKey. Cuando la longitud de la clave llega a 2048 o más, es difícil encontrar los documentos correspondientes para describir cuál es su formato en este momento. Y PKCS8 funciona muy bien. </ B>

int ExportKey() {
  int errCode = 0;

  NCRYPT_PROV_HANDLE prov = NULL;
  NCRYPT_KEY_HANDLE  key = NULL;
  BYTE blob[0x1000] = {0};
  DWORD blobLen = 0x1000;

  if (errCode = NCryptOpenStorageProvider(&prov, MS_KEY_STORAGE_PROVIDER, 0)) goto done;
  if (errCode = NCryptOpenKey(prov, &key, L"TestRSAKey", 0, 0)) goto done;
  if (errCode = NCryptExportKey(key, NULL, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, NULL, blob, blobLen, &blobLen, 0)) goto done;

done:
  if (prov) NCryptFreeObject(prov);
  if (key) NCryptFreeObject(key);
  return errCode;
}

Cuando ejecuta la función y un controlador de clave, si obtiene el código de error 0x80090029, confirme que el valor del atributo NCRYPT_EXPORT_POLICY_PROPERTY de su clave contiene NCRYPT_ALLOW_EXPORT_FLAG y NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG. El motivo para establecer la propiedad Key creada en este valor).

Si su Clave no contiene NCRYPT_ALLOW_EXPORT_FLAG y NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG, significa que su Clave no se puede exportar, y solo puede usar el Mango de la Clave para hacer otro trabajo.

Si el atributo de su clave solo contiene NCRYPT_ALLOW_EXPORT_FLAG, significa que no puede exportar su certificado como texto sin formato. En este momento, debe establecer el segundo parámetro de NCryptExportKey en un valor no NULL. Personalmente, le resultará muy problemático, si Tenga el código correspondiente, ¡gracias por compartirlo conmigo!

Un poco de experiencia personal, si su clave es un PFX importado por los usuarios a través de CryptAPI o manualmente, en la plataforma Win10, es probable que su clave solo tenga la marca NCRYPT_ALLOW_EXPORT_FLAG, y no admite la exportación a texto sin formato. ¡Si me equivoco, hágamelo saber!

Importar clave a la tienda de Windows

En muchos casos, no siempre usamos el sistema para crear la Clave directamente, sino que usamos nuestra Clave existente. Luego, cuando desee que su Clave funcione con la API CNG, será imprescindible importar su Clave en el sistema Trabajo. Tenga en cuenta que el ejemplo que damos aquí guardará la Clave en el sistema. Si solo desea obtener el Mango de la Clave sin importar la Clave en el KSP, solo necesita establecer el nombre de la Clave.

Aquí importaremos la clave de formato PKCS8 al sistema. Si su clave está en otro formato, tiene dos opciones: convertirla al formato PKCS8 y usar el siguiente método para importar o encontrar otros métodos disponibles.

Hay dos puntos que vale la pena mencionar aquí:
<código> NCryptBufferDesc * pParameterList </ code> Este parámetro se puede usar para establecer la información del parámetro de la clave. Aquí usamos este parámetro para especificar el nombre de la clave que se importará al sistema. Si la clave se configura específicamente Nombre, la clave será una clave temporal, no se almacenará en la ventana.
<Code> DWORD dwFlags </ code> Si necesita establecer la propiedad Key después de importar la clave, entonces debe incluir NCRYPT_DO_NOT_FINALIZE_FLAG en este parámetro Mark. En el ejemplo, después de importar la clave, necesitamos establecer la propiedad NCRYPT_EXPORT_POLICY_PROPERTY de la clave, por lo que utilizamos la marca NCRYPT_DO_NOT_FINALIZE_FLAG. Si no usó la NCRYPT_DO_NOT_FINALIZE_FLAG, no llame al método NCryptinal.

int ImportKey() {
  BYTE blob[] = { 0x30,0x82,0x04,0xbd,0x02,0x01,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x82,0x04,0xa7,0x30,0x82,0x04,0xa3,0x02,0x01,
0x00,0x02,0x82,0x01,0x01,0x00,0xad,0xaa,0x8c,0x75,0x51,0x15,0x23,0x55,0xc7,0xec,0x7f,0x0b,0x85,0xf9,0x4b,0x18,0x10,0x60,0xdb,0x3d,0xc2,0xd2,0xcf,0xa6,0x8d,0x09,
0x8a,0xc9,0x7a,0x0e,0x80,0xb8,0x60,0x5a,0x20,0xe7,0xcb,0x52,0x33,0xc0,0xa3,0xc8,0x33,0x05,0xb0,0x45,0x34,0x49,0x59,0x0d,0xff,0xed,0xe5,0xe9,0x42,0xc4,0x05,0x82,
0x1a,0x92,0x67,0x24,0xea,0xc6,0x2a,0x07,0x67,0x07,0x65,0xa9,0xb8,0xe8,0x25,0xa2,0x16,0xe5,0x47,0xf2,0x79,0x98,0xcd,0x7c,0xce,0xbc,0x28,0x95,0x5f,0x9a,0xcd,0x70,
0x30,0xbb,0x7c,0xc9,0xc1,0x55,0xac,0x06,0x42,0xa8,0x86,0x78,0x47,0x69,0xa0,0xfb,0x5e,0x10,0x01,0xe4,0x3a,0xbc,0x09,0xb3,0xfd,0x3f,0x3d,0x3c,0x47,0xe7,0xd2,0x8f,
0xaf,0x2f,0x04,0x38,0x74,0xdc,0x3b,0x74,0x31,0xfb,0x55,0x39,0x94,0xeb,0xe3,0x7c,0x17,0x8d,0x51,0x50,0xa2,0x25,0x87,0x4b,0xfb,0xd2,0x3c,0xb6,0x70,0x45,0xd1,0x55,
0xb0,0x8e,0x9d,0x24,0xcb,0xd7,0xa0,0xc2,0xdd,0xfa,0x7b,0xa4,0x3f,0xd3,0xbe,0x7e,0x09,0x87,0x46,0x37,0xda,0x29,0x7c,0x95,0x85,0x0d,0x6d,0xfc,0xbf,0xbf,0x41,0xbe,
0x79,0x2c,0x83,0x87,0x1b,0x6f,0x24,0x8a,0x60,0x85,0x36,0xf6,0xcb,0x63,0x0c,0x66,0x16,0x0b,0x97,0x4a,0xdc,0xdb,0x91,0x0d,0xf9,0x1d,0x7e,0xae,0xbc,0xd9,0x77,0x39,
0x38,0x3e,0x7b,0x04,0x92,0x71,0x94,0x18,0x66,0xc8,0x77,0x5e,0x5c,0x42,0x16,0xc7,0x18,0x61,0x5a,0xdd,0x4f,0xaf,0x77,0x9a,0x14,0xba,0x39,0x98,0x22,0x73,0x49,0xfa,
0x73,0x2b,0x6d,0x0c,0x3b,0x27,0x02,0x03,0x01,0x00,0x01,0x02,0x82,0x01,0x00,0x2b,0xd2,0xef,0xe2,0xe2,0xf5,0x2c,0x97,0x86,0xfd,0xdd,0x09,0x71,0x63,0x79,0x59,0xb7,
0x38,0x59,0xda,0xfa,0x00,0xec,0xb9,0xa0,0xb9,0x99,0xb6,0x42,0x00,0xca,0xe6,0xbc,0x19,0xc2,0x57,0xfb,0xec,0xe0,0x76,0x6a,0x5e,0x28,0xd1,0xf4,0xab,0x62,0x08,0x68,
0x5a,0xaa,0x0c,0xc4,0x89,0xda,0x79,0x50,0xd2,0x86,0x16,0x0f,0xc5,0x37,0x21,0x8e,0x95,0x93,0xa0,0x40,0x3d,0x56,0x15,0xee,0xf9,0x3a,0x41,0xdd,0xa8,0x08,0x9b,0x50,
0xaf,0x80,0x13,0xe7,0x41,0xda,0x80,0x5b,0xfb,0x45,0xb0,0xea,0x4a,0x97,0x69,0x21,0x21,0xeb,0x4c,0x4f,0xb2,0xa6,0x82,0xb7,0x46,0xf7,0x73,0x9e,0xa6,0x93,0x53,0xc4,
0x37,0x11,0x5f,0x15,0xfa,0xd2,0x42,0x63,0xd6,0x32,0x64,0xf0,0xf1,0xb6,0x3b,0x3a,0xb2,0xc8,0x25,0xc3,0x80,0xa1,0xa3,0xe7,0xb4,0x35,0xab,0x13,0xa9,0x3a,0x40,0xd1,
0x16,0xf6,0x63,0x62,0x62,0xeb,0x7c,0x58,0x4f,0x56,0x94,0xde,0x28,0x8a,0x48,0xc6,0xf0,0x3b,0x88,0x01,0xd3,0x8b,0xc6,0x0b,0x17,0x01,0x10,0x28,0x00,0x9c,0xd0,0x80,
0xc2,0xe8,0x00,0xdc,0x6b,0x37,0x39,0x1c,0xef,0x78,0x34,0x1d,0x49,0x12,0xd4,0x66,0x88,0x20,0x87,0xe2,0x1e,0x2b,0x05,0x26,0x8a,0xa7,0xd0,0x3d,0xe7,0xd0,0x47,0xed,
0xbe,0x1f,0xec,0xd6,0xa1,0xd3,0xe2,0x0e,0xb5,0xe5,0x3c,0xc2,0x83,0x69,0x77,0x36,0x9d,0x80,0x2b,0xe9,0xe1,0x14,0xe0,0xd5,0x27,0x62,0x35,0xc1,0x40,0xc6,0xf2,0x6e,
0xdb,0xc1,0x58,0xb8,0x9c,0xbc,0x83,0x36,0x81,0xfb,0x70,0xae,0x0c,0x5c,0xc1,0x02,0x81,0x81,0x00,0xd2,0x5f,0x19,0x94,0x11,0xb8,0xdc,0x77,0x2e,0x93,0x15,0x50,0x09,
0xa9,0x20,0xf0,0x1b,0xd1,0x3d,0x4a,0x1d,0x2c,0xb6,0x98,0xec,0x11,0xf1,0xe8,0xa0,0x85,0x4c,0xf8,0x14,0x27,0x80,0x26,0xff,0x78,0xa1,0x17,0x52,0xa3,0xbf,0xf6,0xc6,
0x86,0xab,0xca,0x5f,0x1e,0x5e,0x8f,0x78,0x5e,0x71,0x7d,0x2c,0x57,0xbe,0xda,0x80,0xa2,0x8b,0x6a,0x88,0xab,0xcd,0x78,0xc3,0x67,0xf6,0xb5,0x60,0x96,0x5c,0x24,0xac,
0x8c,0x4b,0x77,0x36,0xe2,0x97,0x16,0x87,0x6a,0x03,0xa7,0x36,0x4a,0xdf,0x5d,0xc3,0x6f,0x1f,0x60,0xfd,0x40,0x60,0x0e,0xca,0xb9,0x25,0x37,0xfa,0x50,0xc3,0x82,0x2f,
0x3a,0xeb,0x1b,0xd5,0xe0,0x6f,0x13,0x17,0x7d,0xa4,0xd2,0x97,0xe7,0xd7,0xbb,0x32,0x84,0x1e,0x77,0x02,0x81,0x81,0x00,0xd3,0x55,0x62,0x53,0x35,0x29,0xa5,0x68,0x65,
0x28,0x74,0x16,0x30,0x66,0x3e,0x95,0x8e,0xc6,0xb1,0xdd,0x37,0xae,0x69,0xe7,0xc8,0x62,0x81,0x11,0x57,0x57,0x92,0x2b,0xd8,0x21,0x98,0xf4,0x3f,0xe6,0x6e,0xd1,0x5d,
0xff,0x6f,0x90,0x6b,0x9e,0x68,0x47,0x50,0x6e,0xdf,0x5a,0x12,0x49,0x04,0xe9,0x42,0x7f,0xe1,0x3e,0x05,0x0a,0xa3,0xee,0xca,0xeb,0x40,0x4b,0x89,0x2a,0xa1,0x3c,0x2e,
0xa5,0xad,0xa8,0xc9,0x5e,0xa7,0x70,0x55,0x3f,0x04,0x1d,0x17,0xcb,0xca,0x21,0xf5,0xc3,0x68,0x68,0xb9,0x50,0x98,0xd3,0x3a,0x2c,0x29,0x21,0x3b,0x42,0x12,0x92,0x34,
0xda,0xc5,0xbb,0x0c,0xb2,0xb4,0x86,0x6a,0x4e,0x3f,0x43,0x99,0xc4,0xb7,0x85,0x97,0x36,0x75,0x61,0x28,0xd6,0x84,0xd1,0x02,0x81,0x80,0x36,0x9b,0xa1,0x14,0x22,0x95,
0x8e,0x05,0x11,0xfd,0xf4,0x26,0x56,0x9b,0xa4,0x85,0x2f,0x73,0x5d,0x29,0x83,0xf1,0x3b,0x64,0xee,0xc2,0xa9,0xbc,0xed,0x0e,0x2d,0x30,0xa8,0x6a,0xa8,0x85,0x77,0x03,
0x65,0x2d,0x9c,0xb2,0x0c,0xfe,0x8e,0x02,0x1f,0x4d,0xe4,0xeb,0x09,0x38,0xcc,0xd2,0x17,0x3b,0x9a,0xeb,0x1c,0x0b,0xb4,0x20,0x7d,0x78,0x26,0x0a,0x12,0xc8,0x2a,0x51,
0x2e,0x65,0x5e,0xb1,0x29,0x32,0x0b,0xe8,0x4f,0x1e,0x9f,0x0c,0xaa,0x93,0x9a,0x8b,0x16,0x6f,0xad,0x54,0x3a,0x2f,0x28,0xb0,0x0b,0xc1,0x2d,0x7c,0x2c,0x73,0x2a,0x84,
0x6c,0xf8,0xde,0xed,0x60,0x12,0xc7,0x17,0xd0,0x37,0xe5,0x88,0xe0,0xcc,0x5f,0xe8,0xa9,0x84,0x51,0x12,0x49,0x99,0xba,0x3f,0x39,0x79,0x02,0x81,0x80,0x74,0x65,0x92,
0xc2,0x41,0x85,0xae,0x94,0xd1,0x22,0x76,0xcd,0xc1,0xda,0x8e,0x9d,0xd1,0x05,0x9e,0xf1,0x38,0xb9,0xd7,0x9a,0xd1,0xc3,0x6f,0x53,0x1d,0xc8,0x1d,0xba,0x08,0x50,0x78,
0xee,0x0e,0x43,0xdc,0xc5,0x74,0x00,0x3c,0x72,0x4e,0xd3,0xf0,0x9b,0x56,0xb1,0xba,0x52,0xe1,0xbf,0x55,0xf5,0x23,0xab,0x4b,0x63,0xdd,0x62,0xfe,0xe7,0x86,0xdc,0x0b,
0x8d,0x8e,0xfe,0xeb,0xcf,0x39,0xe2,0x06,0xc3,0xf0,0x25,0x32,0x13,0xac,0xe0,0x08,0x63,0xfd,0xb7,0x40,0x9d,0x73,0xbf,0x2c,0xc2,0x81,0x4e,0xe2,0xdd,0x74,0x2c,0xde,
0x7a,0x6f,0x28,0xf5,0x11,0x92,0x0a,0xec,0xdd,0x19,0x21,0x54,0x4c,0xb4,0x40,0x64,0x97,0xd7,0x19,0x81,0xfb,0x12,0x4d,0xec,0x58,0x97,0x25,0x90,0x01,0x02,0x81,0x81,
0x00,0x9d,0xf3,0x78,0x3e,0x39,0xb6,0x45,0x97,0x2d,0xb2,0xf2,0xdb,0xe3,0xa8,0xe9,0x8e,0x58,0xd7,0x6b,0xfb,0x11,0x25,0x77,0x6b,0xd5,0xd6,0x61,0x39,0xbb,0x04,0x15,
0xc2,0x7d,0xf9,0xc7,0xf1,0x1a,0xce,0xe5,0x40,0x84,0x26,0x83,0x13,0xb4,0x41,0x49,0xa2,0x42,0x71,0x3c,0xed,0x72,0x17,0xa9,0x2a,0x85,0x25,0xea,0x5b,0xf3,0x6e,0xd6,
0x5b,0x49,0xc8,0xda,0xe4,0xaa,0xa4,0xa5,0x96,0x31,0xaa,0x7e,0x10,0xd7,0x8a,0xf8,0x16,0xe0,0xe0,0x21,0x64,0x22,0xfb,0x1c,0x74,0x27,0xbe,0xf7,0x0f,0x0c,0x94,0x4b,
0x47,0xf4,0xfe,0x58,0xe1,0x72,0xb1,0x08,0xac,0x93,0xb5,0x06,0x29,0x78,0xb8,0xb3,0xf8,0xd4,0x2f,0x4e,0x43,0x3a,0x0c,0x14,0x8b,0x00,0xd2,0xd5,0x21,0x93,0x8c,0x5d,
0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 
  };
  DWORD blobLen = 0x4c1;

  int errCode = 0;

  NCRYPT_PROV_HANDLE prov = NULL;
  NCRYPT_KEY_HANDLE  key = NULL;
  DWORD policy = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;

  LPCWSTR name = L"ImportedKey";
  BCryptBuffer cb[1];
  cb[0].BufferType = NCRYPTBUFFER_PKCS_KEY_NAME;
  cb[0].pvBuffer = (void*)name;
  cb[0].cbBuffer = lstrlenW(name) * 2 + 2;
  NCryptBufferDesc desc;
  desc.ulVersion = 0;
  desc.pBuffers = cb;
  desc.cBuffers = 1;
  if (errCode = NCryptOpenStorageProvider(&prov, MS_KEY_STORAGE_PROVIDER, 0)) goto done;
  if (errCode = NCryptImportKey(prov, NULL, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, &desc, &key, blob, blobLen, NCRYPT_DO_NOT_FINALIZE_FLAG)) goto done;
  if (errCode = NCryptSetProperty(key, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)(&policy), sizeof(policy), NCRYPT_PERSIST_FLAG)) goto done;
  if (errCode = NCryptFinalizeKey(key, 0)) goto done;

done:
  if (prov) NCryptFreeObject(prov);
  if (key) NCryptFreeObject(key);
  return errCode;
}

Una vez completada la importación, puede usar ListKeys para verificar si su importación se realizó correctamente.

¡FIN!

27 artículos originales publicados · 31 elogiados · 40,000+ vistas

Supongo que te gusta

Origin blog.csdn.net/zhaoruixiang1111/article/details/102805653
Recomendado
Clasificación