Función CryptDeriveKey (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 CryptDeriveKey genera claves de sesión criptográficas derivadas de un valor de datos base. Esta función garantiza que, cuando se usan el mismo proveedor de servicios criptográficos (CSP) y algoritmos, las claves generadas a partir de los mismos datos base son idénticas. Los datos base pueden ser una contraseña o cualquier otro dato de usuario.

Esta función es la misma que CryptGenKey, salvo que las claves de sesión generadas se derivan de datos base en lugar de ser aleatorias. CryptDeriveKey solo se puede usar para generar claves de sesión. No puede generar pares de claves públicas y privadas.

Se devuelve un identificador a la clave de sesión en el parámetro phKey . Este identificador se puede usar con cualquier función CryptoAPI que requiera un identificador de clave.

Sintaxis

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

Parámetros

[in] hProv

Un identificador HCRYPTPROV de un CSP creado por una llamada a CryptAcquireContext.

[in] Algid

Estructura ALG_ID que identifica el algoritmo de cifrado simétrico para el que se va a generar la clave. Es probable que los algoritmos disponibles sean diferentes para cada CSP. Para obtener más información sobre qué identificador de algoritmo usan los distintos proveedores para las especificaciones de clave AT_KEYEXCHANGE y AT_SIGNATURE, consulte ALG_ID.

Para obtener más información sobre ALG_ID valores que se usarán con el proveedor criptográfico base de Microsoft, vea Algoritmos de proveedor base. Para obtener más información sobre ALG_ID valores que se usarán con el proveedor criptográfico seguro de Microsoft o el proveedor criptográfico mejorado de Microsoft, consulte Algoritmos de proveedor mejorados.

[in] hBaseData

Identificador de un objeto hash que se ha alimentado con los datos base exactos.

Para obtener este identificador, una aplicación debe crear primero un objeto hash con CryptCreateHash y, a continuación, agregar los datos base al objeto hash con CryptHashData. Este proceso se describe en detalle en Hashes y firmas digitales.

[in] dwFlags

Especifica el tipo de clave generada.

Los tamaños de una clave de sesión se pueden establecer cuando se genera la clave. El tamaño de la 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 sesión RC4 de 128 bits, el valor 0x00800000 se combina con cualquier otro valor predefinido dwFlags con una operación OR bit a bit. Debido a la modificación de 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.

Los 16 bits inferiores de este parámetro pueden ser cero o puede especificar una o varias de las marcas siguientes mediante el operador OR bit a bit para combinarlos.

Valor Significado
CRYPT_CREATE_SALT
Normalmente, cuando se realiza una clave de sesión a partir de un valor hash , hay un número de bits sobrantes. Por ejemplo, si el valor hash es de 128 bits y la clave de sesión es de 40 bits, quedan 88 bits.

Si se establece esta marca, a la clave se le asigna un valor de sal basado en los bits de valor hash sin usar. 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 (mediante CryptExportKey), el valor de sal también debe obtenerse y mantenerse con la clave BLOB.

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

Si no se establece esta marca, la clave de sesión no se puede exportar. Esto significa que la clave solo está disponible dentro de la sesión actual y solo la aplicación que la creó puede usarla.

Esta marca no se aplica a pares de claves públicas o privadas.

CRYPT_NO_SALT
Esta marca especifica que se asigna un valor sin sal para una clave simétrica de 40 bits. Para obtener más información, consulte Funcionalidad de valor de sal.
CRYPT_UPDATE_KEY
Algunos CSP usan claves de sesión derivadas de varios valores hash. Cuando este es el caso, se debe llamar a CryptDeriveKey varias veces.

Si se establece esta marca, no se genera una nueva clave de sesión. En su lugar, se modifica la clave especificada por phKey . El comportamiento preciso de esta marca depende del tipo de clave que se va a generar y del CSP concreto que se está usando.

Los proveedores de servicios criptográficos de Microsoft omiten esta marca.

CRYPT_SERVER
1024 (0x400)
Esta marca solo se usa con proveedores de Schannel . Si se establece esta marca, la clave que se va a generar es una clave de escritura de servidor; de lo contrario, es una clave de escritura de cliente.

[in, out] phKey

Puntero a una variable HCRYPTKEY para recibir la dirección del identificador de la clave recién generada. Cuando haya terminado de usar la clave, libere el identificador llamando a la función CryptDestroyKey .

Valor devuelto

Si la función se ejecuta correctamente, la función devuelve un valor distinto de cero (TRUE).

Si se produce un error en la función, devuelve cero (FALSE). 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_HASH
El parámetro hBaseData no contiene un identificador válido para un objeto hash.
NTE_BAD_HASH_STATE
Se intentó agregar datos a un objeto hash que ya está marcado como "finalizado".
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

Cuando se generan claves para cifrados de bloquessimétricos, la clave se configura de forma predeterminada 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 cifrar datos de forma masiva. Para cambiar estos parámetros, use la función CryptSetKeyParam .

La función CryptDeriveKey completa el hash. Después de llamar a CryptDeriveKey , no se pueden agregar más datos al hash. Se produce un error en las llamadas adicionales a CryptHashData o CryptHashSessionKey . Una vez finalizada la aplicación con el hash, se debe llamar a CryptDestroyHash para destruir el objeto hash.

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

  • Para enumerar los algoritmos que admite el CSP y obtener las longitudes de clave máximas y mínimas para cada algoritmo, 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.
Deje que n sea la longitud de clave derivada necesaria, en bytes. La clave derivada es el primer n bytes del valor hash después de que CryptDeriveKey haya completado el cálculo del hash. Si el hash no es miembro de la familia SHA-2 y la clave necesaria es para 3DES o AES, la clave se deriva de la siguiente manera:
  1. Forme un búfer de 64 bytes repitiendo la constante 0x36 64 veces. Deje que k sea la longitud del valor hash representado por el parámetro de entrada hBaseData. Establezca los primeros k bytes del búfer en el resultado de una operación XOR de los primeros k bytes del búfer con el valor hash representado por el parámetro de entrada hBaseData.
  2. Forme un búfer de 64 bytes repitiendo la constante 0x5C 64 veces. Establezca los primeros k bytes del búfer en el resultado de una operación XOR de los primeros k bytes del búfer con el valor hash representado por el parámetro de entrada hBaseData.
  3. Aplica un hash al resultado del paso 1 mediante el mismo algoritmo hash que el utilizado para calcular el valor hash representado por el parámetro hBaseData .
  4. Para aplicar un algoritmo hash al resultado del paso 2, use el mismo algoritmo hash que se usó para calcular el valor hash representado por el parámetro hBaseData .
  5. Concatene el resultado del paso 3 con el resultado del paso 4.
  6. Use los primeros n bytes del resultado del paso 5 como clave derivada.
El proveedor de servicios criptográficos completo RSA predeterminado es el proveedor de servicios criptográficos seguros RSA de Microsoft. La firma de DSS predeterminada Diffie-Hellman proveedor de servicios criptográficos es el proveedor de servicios criptográficos de DSS mejorado de Microsoft Diffie-Hellman. Cada uno de estos CSP tiene una longitud de clave simétrica de 128 bits predeterminada para RC2 y RC4.

En la tabla siguiente se enumeran las longitudes de clave mínimas, predeterminadas y máximas para la clave de sesión por algoritmo y proveedor.

Proveedor Algoritmos Longitud mínima de clave Longitud de clave predeterminada Longitud máxima de clave
MS Base RC4 y RC2 40 40 56
MS Base DES 56 56 56
MS Enhanced RC4 y RC2 40 128 128
MS Enhanced DES 56 56 56
MS Enhanced 3DES 112 112 112 112
MS Enhanced 3DES 168 168 168
MS Strong RC4 y RC2 40 128 128
MS Strong DES 56 56 56
MS Strong 3DES 112 112 112 112
MS Strong 3DES 168 168 168
DSS/DH Base RC4 y RC2 40 40 56
DSS/DH Base Cylink MEK 40 40 40
DSS/DH Base DES 56 56 56
DSS/DH Enh RC4 y RC2 40 128 128
DSS/DH Enh Cylink MEK 40 40 40
DSS/DH Enh DES 56 56 56
DSS/DH Enh 3DES 112 112 112 112
DSS/DH Enh 3DES 168 168 168
 

Ejemplos

Para obtener un ejemplo que usa esta función, vea Ejemplo de programa C: derivar una clave de sesión de una contraseña.

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

CryptCreateHash

CryptDestroyHash

CryptDestroyKey

CryptExportKey

CryptGenKey

CryptGetKeyParam

CryptHashData

CryptHashSessionKey

CryptSetKeyParam

Generación de claves y funciones de Exchange