Compartir a través de


Función CryptDeriveKey (wincrypt.h)

importante Esta API está en desuso. El software nuevo y existente debe empezar a usar las API de 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 los mismos 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 aleatorios. 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

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. Los algoritmos disponibles probablemente serán 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, vea ALG_ID.

Para obtener más información sobre los valores de ALG_ID 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 con el proveedor criptográfico mejorado de Microsoft, consulte algoritmos de proveedor mejorados.

[in] hBaseData

Identificador de un objeto hash que se ha alimentado 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 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 de RC4 de 128 bits, el valor 0x00800000 se combina con cualquier otro dwFlags valor predefinido con una operación or bit abit. 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 bitOR para combinarlos.

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

Si se establece esta marca, a la clave se le asigna un valor de salt en función de 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 se exportan las claves con valores de sal distinto de cero (mediante CryptExportKey), el valor de sal también debe obtenerse y mantenerse con la clave BLOB de .

CRYPT_EXPORTABLE
Si se establece esta marca, la clave de sesión se puede transferir fuera del CSP a un BLOB de clave a través de 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 en la sesión actual y solo la aplicación que creó puede usarla.

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

CRYPT_NO_SALT
Esta marca especifica que no se asigna ningún valor de sal para una clave simétrica de 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, CryptDeriveKey se debe llamar 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 genera y del CSP en particular que se usa.

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 de 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. En la tabla siguiente se enumeran algunos códigos de error posibles.

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.

Observaciones

Cuando se generan claves para cifrado de bloques simé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 el cifrado masivo de datos. 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 producen errores en 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 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 porque esto puede provocar problemas de rendimiento.
  • Después de elegir la longitud de clave deseada, use los 16 bits superiores del parámetro dwFlags de para especificar la longitud de la clave.
Deje que n ser la longitud de clave derivada necesaria, en bytes. La clave derivada es la primera n bytes del valor hash después de que CryptDeriveKey haya completado el cálculo de 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 ser la longitud del valor hash representado por el parámetro de entrada hBaseData. Establezca el primer k bytes del búfer en el resultado de una operación de XOR del primer 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 el primer k bytes del búfer en el resultado de una operación de XOR del primer k bytes del búfer con el valor hash representado por el parámetro de entrada hBaseData.
  3. Hash del resultado del paso 1 mediante el mismo algoritmo hash que el usado para calcular el valor hash representado por el parámetro hBaseData.
  4. Hash del resultado del paso 2 mediante el mismo algoritmo hash que el usado 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 el primer 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 mínimas, predeterminadas y máximas de clave 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 use esta función, vea Programa C de ejemplo: derivar una clave de sesión de unde contraseña.

Requisitos

Requisito Valor
cliente mínimo admitido Windows XP [solo aplicaciones de escritorio]
servidor mínimo admitido Windows Server 2003 [solo aplicaciones de escritorio]
de la plataforma de destino de Windows
encabezado de wincrypt.h
biblioteca de Advapi32.lib
DLL de Advapi32.dll

Consulte también

CryptAcquireContext

CryptCreateHash

CryptDestroyHash

CryptDestroyKey

CryptExportKey

CryptGenKey

CryptGetKeyParam

CryptHashData

CryptHashSessionKey

CryptSetKeyParam

de generación de claves y funciones de Exchange de