Función CryptGenKey (wincrypt.h)

Importante Esta API está en desuso. El software nuevo y existente debe empezar a usar las API cryptography Next Generation. Microsoft puede quitar esta API en futuras versiones.
 
La función CryptGenKey genera una clave de sesión criptográfica aleatoria o un par de claves públicas o privadas. Se devuelve un identificador para la clave o el par de claves en phKey. A continuación, este identificador se puede usar según sea necesario con cualquier función CryptoAPI que requiera un identificador de clave.

La aplicación que realiza la llamada debe especificar el algoritmo al llamar a esta función. Dado que este tipo de algoritmo se mantiene agrupado con la clave, la aplicación no necesita especificar el algoritmo más adelante cuando se realizan las operaciones criptográficas reales.

Sintaxis

BOOL CryptGenKey(
  [in]  HCRYPTPROV hProv,
  [in]  ALG_ID     Algid,
  [in]  DWORD      dwFlags,
  [out] HCRYPTKEY  *phKey
);

Parámetros

[in] hProv

Identificador de un proveedor de servicios criptográficos (CSP) creado por una llamada a CryptAcquireContext.

[in] Algid

Valor ALG_ID que identifica el algoritmo para el que se va a generar la clave. Los valores de este parámetro varían en función del CSP usado.

Para obtener ALG_ID valores que se usarán con el proveedor criptográfico base de Microsoft, consulte Algoritmos de proveedor base.

Para obtener ALG_ID valores que se usarán con el proveedor criptográfico seguro de Microsoft o con el proveedor criptográfico mejorado de Microsoft, consulte Algoritmos de proveedor mejorados.

Para un CSP de Diffie-Hellman, use uno de los valores siguientes.

Valor Significado
CALG_DH_EPHEM
Especifica una clave de Diffie-Hellman "Efímero".
CALG_DH_SF
Especifica una clave de Diffie-Hellman "Almacenar y reenviar".
 

Además de generar claves de sesión para algoritmos simétricos, esta función también puede generar pares de claves públicas y privadas. Cada cliente cryptoAPI generalmente posee dos pares de claves públicas y privadas. Para generar uno de estos pares de claves, establezca el parámetro Algid en uno de los siguientes valores.

Valor Significado
AT_KEYEXCHANGE
Intercambio de claves
AT_SIGNATURE
Firma digital
 
Nota Cuando se especifican especificaciones clave AT_KEYEXCHANGE y AT_SIGNATURE, los identificadores de algoritmo que se usan para generar la clave dependen del proveedor usado. Como resultado, para estas especificaciones clave, los valores devueltos de CryptGetKeyParam (cuando se especifica el parámetro KP_ALGID) dependen del proveedor usado. Para determinar qué identificador de algoritmo usan los distintos proveedores para las especificaciones de clave AT_KEYEXCHANGE y AT_SIGNATURE, consulte ALG_ID.
 

[in] dwFlags

Especifica el tipo de clave generada. Los tamaños de una clave de sesión, la clave de firma RSA y las claves de intercambio de claves RSA se pueden establecer cuando se genera la clave. El tamaño de clave, que representa la longitud del módulo de clave en bits, se establece con los 16 bits superiores de este parámetro. Por lo tanto, si se va a generar una clave de firma RSA de 2048 bits, el valor 0x08000000 se combina con cualquier otro valor predefinido dwFlags con una operación OR bit a bit. Los 16 bits superiores de 0x08000000 son 0x0800 o decimales 2048. El valor de RSA1024BIT_KEY se puede usar para especificar una clave RSA de 1024 bits.

Debido a cambiar las restricciones de control de exportación, el CSP predeterminado y la longitud de clave predeterminada pueden cambiar entre las versiones del sistema operativo. Es importante que tanto el cifrado como el descifrado usen el mismo CSP y que la longitud de la clave se establezca explícitamente mediante el parámetro dwFlags para garantizar la interoperabilidad en distintas plataformas del sistema operativo.

En concreto, el proveedor de servicios criptográficos completo RSA predeterminado es el proveedor criptográfico seguro RSA de Microsoft. La firma de DSS predeterminada Diffie-Hellman proveedor de servicios criptográficos es el proveedor de servicios criptográficos mejorado de Microsoft Diffie-Hellman DSS. Cada uno de estos CSP tiene una longitud de clave simétrica de 128 bits predeterminada para RC2 y RC4 y una longitud de clave predeterminada de 1024 bits para algoritmos de clave pública.

Si los 16 bits superiores son cero, se genera el tamaño de clave predeterminado. Si se especifica una clave mayor que el máximo o menor que el mínimo, se produce un error en la llamada con el código de ERROR_INVALID_PARAMETER.

En la tabla siguiente se enumeran las longitudes mínimas, predeterminadas y máximas de firma y clave de intercambio a partir de Windows XP.

Tipo de clave y proveedor Longitud mínima Longitud predeterminada Longitud máxima
Proveedor base RSA

Signature y ExchangeKeys

384 512 16 384
Proveedores seguros y mejorados de RSA

Claves de firma y intercambio

384 1024 16 384
Proveedores base de DSS

Claves de firma

512 1024 1024
Proveedores base de DSS

Claves de intercambio

No aplicable No aplicable No aplicable
Proveedores base DSS/DH

Claves de firma

512 1024 1024
Proveedores base DSS/DH

Claves de intercambio

512 512 1024
Proveedores mejorados de DSS/DH

Claves de firma

512 1024 1024
Proveedores mejorados de DSS/DH

Claves de intercambio

512 1024 4 096
 

Para obtener longitudes de clave de sesión, consulte CryptDeriveKey.

Para obtener más información sobre las claves generadas mediante proveedores de Microsoft, consulte Proveedores de servicios criptográficos de Microsoft.

Los 16 bits inferiores de este parámetro pueden ser cero o una combinación de uno o varios de los valores siguientes.

Valor Significado
CRYPT_ARCHIVABLE
Si se establece esta marca, la clave se puede exportar hasta que se cierre su identificador mediante una llamada a CryptDestroyKey. Esto permite exportar las claves recién generadas al crearse para archivar o recuperar claves. Una vez cerrado el identificador, la clave ya no se puede exportar.
CRYPT_CREATE_IV
Esta marca no se usa.
CRYPT_CREATE_SALT
Si se establece esta marca, la clave se asigna automáticamente a un valor de sal aleatorio. Puede recuperar este valor de sal mediante la función CryptGetKeyParam con el parámetro dwParam establecido en KP_SALT.

Si no se establece esta marca, la clave recibe un valor de sal de cero.

Cuando las claves con valores de sal distinto de cero se exportan (a través de CryptExportKey), el valor de sal también debe obtenerse y mantenerse con la clave BLOB.

CRYPT_DATA_KEY
Esta marca no se usa.
CRYPT_EXPORTABLE
Si se establece esta marca, la clave se puede transferir fuera del CSP a una clave BLOB mediante la función CryptExportKey . Dado que las claves de sesión generalmente deben ser exportables, esta marca normalmente debe establecerse cuando se crean.

Si no se establece esta marca, la clave no se puede exportar. En el caso de una clave de sesión, esto significa que la clave solo está disponible dentro de la sesión actual y solo la aplicación que la creó podrá usarla. En el caso de un par de claves pública o privada, esto significa que la clave privada no se puede transportar ni realizar una copia de seguridad.

Esta marca solo se aplica a la clave de sesión y a los blobs de clave privada. No se aplica a las claves públicas, que siempre se pueden exportar.

CRYPT_FORCE_KEY_PROTECTION_HIGH
Esta marca especifica una protección segura de claves. Cuando se establece esta marca, se solicita al usuario que escriba una contraseña para la clave cuando se cree la clave. Se pedirá al usuario que escriba la contraseña cada vez que se use esta clave.

Esta marca solo la usan los CSP proporcionados por Microsoft. Los CSP de terceros definirán su propio comportamiento para la protección segura de claves.

Si se especifica esta marca, se produce el mismo resultado que llamar a esta función con la marca CRYPT_USER_PROTECTED cuando se especifica protección de clave segura en el registro del sistema.

Si se especifica esta marca y el identificador del proveedor en el parámetro hProv se creó mediante la marca CRYPT_VERIFYCONTEXT o CRYPT_SILENT , esta función establecerá el último error en NTE_SILENT_CONTEXT y devolverá cero.

Windows Server 2003 y Windows XP: Esta marca no se admite.

CRYPT_KEK
Esta marca no se usa.
CRYPT_INITIATOR
Esta marca no se usa.
CRYPT_NO_SALT
Esta marca especifica que se asigna un valor sin sal para una clave simétrica de cuarenta bits. Para obtener más información, consulte Funcionalidad de valor de sal.
CRYPT_ONLINE
Esta marca no se usa.
CRYPT_PREGEN
Esta marca especifica una generación inicial de claves de Diffie-Hellman o DSS. Esta marca solo es útil con Diffie-Hellman y CSP de DSS. Cuando se usa, se usará una longitud de clave predeterminada a menos que se especifique una longitud de clave en los 16 bits superiores del parámetro dwFlags . Si los parámetros que implican longitudes de clave se establecen en una clave PREGEN Diffie-Hellman o DSS mediante CryptSetKeyParam, las longitudes de clave deben ser compatibles con la longitud de clave establecida aquí.
CRYPT_RECIPIENT
Esta marca no se usa.
CRYPT_SF
Esta marca no se usa.
CRYPT_SGCKEY
Esta marca no se usa.
CRYPT_USER_PROTECTED
Si se establece esta marca, se notifica al usuario a través de un cuadro de diálogo u otro método cuando determinadas acciones intentan usar esta clave. El csp que se usa especifica el comportamiento preciso. Si el contexto del proveedor se abrió con la marca CRYPT_SILENT establecida, el uso de esta marca produce un error y el último error se establece en NTE_SILENT_CONTEXT.
CRYPT_VOLATILE
Esta marca no se usa.

[out] phKey

Dirección a la que la función copia el identificador de la clave recién generada. Cuando haya terminado de usar la clave, elimine el identificador de la clave mediante una llamada a la función CryptDestroyKey .

Valor devuelto

Devuelve un valor distinto de cero si es correcto o cero de lo contrario.

Para obtener información de error extendida, llame a GetLastError.

Los códigos de error precedidos por "NTE" se generan mediante el CSP en particular que se usa. Algunos códigos de error posibles se enumeran en la tabla siguiente.

Código devuelto Descripción
ERROR_INVALID_HANDLE
Uno de los parámetros especifica un identificador que no es válido.
ERROR_INVALID_PARAMETER
Uno de los parámetros contiene un valor que no es válido. Suele ser un puntero que no es válido.
NTE_BAD_ALGID
El parámetro Algid especifica un algoritmo que este CSP no admite.
NTE_BAD_FLAGS
El parámetro dwFlags contiene un valor que no es válido.
NTE_BAD_UID
El parámetro hProv no contiene un identificador de contexto válido.
NTE_FAIL
Error en la función de alguna manera inesperada.
NTE_SILENT_CONTEXT
El proveedor no pudo realizar la acción porque el contexto se adquirió como silencioso.

Comentarios

Si se generan claves para cifrados de bloquessimétricos, la clave, de forma predeterminada, se configura en modo de encadenamiento de bloques de cifrado (CBC) con un vector de inicialización de cero. Este modo de cifrado proporciona un buen método predeterminado para el cifrado masivo de datos. Para cambiar estos parámetros, use la función CryptSetKeyParam .

Para elegir una longitud de clave adecuada, se recomiendan los métodos siguientes:

  • Enumerar los algoritmos que admite el CSP y obtener las longitudes de clave máximas y mínimas para cada algoritmo. Para ello, llame a CryptGetProvParam con PP_ENUMALGS_EX.
  • Use las longitudes mínimas y máximas para elegir una longitud de clave adecuada. No siempre es aconsejable elegir la longitud máxima, ya que esto puede provocar problemas de rendimiento.
  • Una vez elegida la longitud de clave deseada, use los 16 bits superiores del parámetro dwFlags para especificar la longitud de la clave.

Ejemplos

En el ejemplo siguiente se muestra la creación de una clave de sesión aleatoria. Para obtener un ejemplo que incluya el contexto completo de este ejemplo, vea Ejemplo de programa C: Cifrado de un archivo. Para obtener otro ejemplo que usa esta función, vea Ejemplo de programa C: descifrar un archivo.

//-------------------------------------------------------------------
//  Declare the handle to the key.
HCRYPTKEY hKey; 
//-------------------------------------------------------------------
//  This example assumes that a cryptographic context 
//  has been acquired, and that it is stored in hCryptProv.
//---------------------------------------------------------------
//  Create a random session key. 

 if(CryptGenKey(
          hCryptProv, 
          ENCRYPT_ALGORITHM, 
          KEYLENGTH | CRYPT_EXPORTABLE, 
          &hKey))
 {
         printf("A session key has been created.\n");
 } 
 else
 {
          printf("Error during CryptGenKey.\n"); 
          exit(1);
 }
//-------------------------------------------------------------------
//  The key created can be exported into a key BLOB that can be
//  written to a file.
//  ...
//  When you have finished using the key, free the resource.
if (!CryptDestroyKey(hKey))
{
          printf("Error during CryptDestroyKey.\n"); 
          exit(1);
}

Requisitos

Requisito Value
Cliente mínimo compatible Windows XP [solo aplicaciones de escritorio]
Servidor mínimo compatible Windows Server 2003 [solo aplicaciones de escritorio]
Plataforma de destino Windows
Encabezado wincrypt.h
Library Advapi32.lib
Archivo DLL Advapi32.dll

Consulte también

CryptAcquireContext

CryptDestroyKey

CryptExportKey

CryptGetKeyParam

CryptImportKey

CryptSetKeyParam

Funciones de generación y intercambio de claves

Problemas de subprocesos con proveedores de servicios criptográficos