Función CryptEncrypt (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 CryptEncrypt cifra los datos. El algoritmo utilizado para cifrar los datos se designa mediante la clave que mantiene el módulo CSP y el parámetro hKey hace referencia a ellos.

Se han realizado cambios importantes para admitir la interoperabilidad de correo electrónico seguro/multipropósito de extensiones de correo de Internet (S/MIME) en CryptoAPI que afectan al control de mensajes sobres. Para obtener más información, vea la sección Comentarios de CryptMsgOpenToEncode.

Importante No se garantiza que la función CryptEncrypt sea segura para subprocesos y puede devolver resultados incorrectos si se invocan simultáneamente por varios autores de llamada.
 

Sintaxis

BOOL CryptEncrypt(
  [in]      HCRYPTKEY  hKey,
  [in]      HCRYPTHASH hHash,
  [in]      BOOL       Final,
  [in]      DWORD      dwFlags,
  [in, out] BYTE       *pbData,
  [in, out] DWORD      *pdwDataLen,
  [in]      DWORD      dwBufLen
);

Parámetros

[in] hKey

Identificador de la clave de cifrado. Una aplicación obtiene este identificador mediante la función CryptGenKey o CryptImportKey .

La clave especifica el algoritmo de cifrado utilizado.

[in] hHash

Identificador de un objeto hash. Si los datos se van a aplicar un algoritmo hash y se cifran simultáneamente, se puede pasar un identificador a un objeto hash en el parámetro hHash . El valor hash se actualiza con el texto no cifrado pasado. Esta opción es útil al generar texto firmado y cifrado.

Antes de llamar a CryptEncrypt, la aplicación debe obtener un identificador para el objeto hash mediante una llamada a la función CryptCreateHash . Una vez completado el cifrado, el valor hash se puede obtener mediante la función CryptGetHashParam o el hash se puede firmar mediante la función CryptSignHash .

Si no se va a realizar ningún hash, este parámetro debe ser NULL.

[in] Final

Valor booleano que especifica si se trata de la última sección de una serie que se va a cifrar. Final se establece en TRUE para el último bloque o solo y en FALSE si hay más bloques que se van a cifrar. Para obtener más información, vea la sección Comentarios.

[in] dwFlags

El siguiente valor dwFlags se define pero se reserva para su uso futuro.

Valor Significado
CRYPT_OAEP
Use el relleno óptimo de cifrado asimétrico (OAEP) (PKCS #1 versión 2). Esta marca solo es compatible con el proveedor criptográfico mejorado de Microsoft con cifrado y descifrado RSA.

[in, out] pbData

Puntero a un búfer que contiene el texto no cifrado que se va a cifrar. El texto no cifrado de este búfer se sobrescribe con el texto cifrado creado por esta función.

El parámetro pdwDataLen apunta a una variable que contiene la longitud, en bytes, del texto no cifrado. El parámetro dwBufLen contiene el tamaño total, en bytes, de este búfer.

Si este parámetro contiene NULL, esta función calculará el tamaño necesario para el texto cifrado y lo colocará en el valor al que apunta el parámetro pdwDataLen .

[in, out] pdwDataLen

Puntero a un valor DWORD que , en la entrada, contiene la longitud, en bytes, del texto no cifrado en el búfer pbData . Al salir, esta DWORD contiene la longitud, en bytes, del texto cifrado escrito en el búfer pbData .

Si el búfer asignado para pbData no es lo suficientemente grande como para contener los datos cifrados, GetLastError devuelve ERROR_MORE_DATA y almacena el tamaño de búfer necesario, en bytes, en el valor DWORD al que apunta pdwDataLen.

Si pbData es NULL, no se devuelve ningún error y la función almacena el tamaño de los datos cifrados, en bytes, en el valor DWORD al que apunta pdwDataLen. Esto permite a una aplicación determinar el tamaño de búfer correcto.

Cuando se usa un cifrado de bloques , esta longitud de datos debe ser un múltiplo del tamaño del bloque a menos que se trata de la sección final de datos que se va a cifrar y el parámetro Final sea TRUE.

[in] dwBufLen

Especifica el tamaño total, en bytes, del búfer pbData de entrada.

Tenga en cuenta que, dependiendo del algoritmo utilizado, el texto cifrado puede ser mayor que el texto sin formato original. En este caso, el búfer pbData debe ser lo suficientemente grande como para contener el texto cifrado y cualquier relleno.

Como regla, si se usa un cifrado de secuencia , el texto cifrado es el mismo tamaño que el texto sin formato. Si se usa un cifrado de bloques , el texto cifrado es hasta una longitud de bloque mayor que el texto no cifrado.

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 concreto que se usa. A continuación se indican algunos códigos de error posibles.

Valor 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
La clave de sesiónhKey especifica un algoritmo que este CSP no admite.
NTE_BAD_DATA
Los datos que se van a cifrar no son válidos. Por ejemplo, cuando se usa un cifrado de bloques y la marca Final es FALSE, el valor especificado por pdwDataLen debe ser un múltiplo del tamaño del bloque.
NTE_BAD_FLAGS
El parámetro dwFlags es distinto de cero.
NTE_BAD_HASH
El parámetro hHash contiene un identificador que no es válido.
NTE_BAD_HASH_STATE
Se intentó agregar datos a un objeto hash que ya está marcado como "finalizado".
NTE_BAD_KEY
El parámetro hKey no contiene un identificador válido para una clave.
NTE_BAD_LEN
El tamaño del búfer de salida es demasiado pequeño para contener el texto cifrado generado.
NTE_BAD_UID
No se encuentra el contexto de CSP que se especificó cuando se creó la clave.
NTE_DOUBLE_ENCRYPT
La aplicación intentó cifrar los mismos datos dos veces.
NTE_FAIL
Error en la función de alguna manera inesperada.
NTE_NO_MEMORY
El CSP se quedó sin memoria durante la operación.

Comentarios

Si se va a cifrar una gran cantidad de datos, se puede realizar en secciones mediante una llamada a CryptEncrypt repetidamente. El parámetro Final debe establecerse en TRUE en la última llamada a CryptEncrypt, para que el motor de cifrado pueda finalizar correctamente el proceso de cifrado. Las siguientes acciones adicionales se realizan cuando Final es TRUE:

  • Si la clave es una clave de cifrado de bloque, los datos se rellenan en un múltiplo del tamaño de bloque del cifrado. Si la longitud de los datos es igual al tamaño de bloque del cifrado, se anexa un bloque adicional de relleno a los datos. Para buscar el tamaño de bloque de un cifrado, use CryptGetKeyParam para obtener el valor KP_BLOCKLEN de la clave.
  • Si el cifrado funciona en modo de encadenamiento, la siguiente operación CryptEncrypt restablece el registro de comentarios del cifrado al valor KP_IV de la clave.
  • Si el cifrado es un cifrado de secuencia, el siguiente CryptEncrypt restablece el cifrado a su estado inicial.

No hay ninguna manera de establecer el registro de comentarios del cifrado en el valor KP_IV de la clave sin establecer el parámetro Final en TRUE. Si esto es necesario, como en el caso de que no desee agregar un bloque de relleno adicional o cambiar el tamaño de cada bloque, puede simularlo creando un duplicado de la clave original mediante la función CryptDuplicateKey y pasando la clave duplicada a la función CryptEncrypt . Esto hace que la KP_IV de la clave original se coloque en la clave duplicada. Después de crear o importar la clave original, no puede usar la clave original para el cifrado porque se cambiará el registro de comentarios de la clave. El pseudocódigo siguiente muestra cómo se puede hacer esto.

// Set the IV for the original key. Do not use the original key for 
// encryption or decryption after doing this because the key's 
// feedback register will get modified and you cannot change it.
CryptSetKeyParam(hOriginalKey, KP_IV, newIV)

while(block = NextBlock())
{
    // Create a duplicate of the original key. This causes the 
    // original key's IV to be copied into the duplicate key's 
    // feedback register.
    hDuplicateKey = CryptDuplicateKey(hOriginalKey)

    // Encrypt the block with the duplicate key.
    CryptEncrypt(hDuplicateKey, block)

    // Destroy the duplicate key. Its feedback register has been 
    // modified by the CryptEncrypt function, so it cannot be used
    // again. It will be re-duplicated in the next iteration of the 
    // loop.
    CryptDestroyKey(hDuplicateKey)
}

El proveedor criptográfico mejorado de Microsoft admite el cifrado directo con claves públicasRSA y descifrado con claves privadas RSA. El cifrado usa relleno PKCS #1. En el descifrado, se comprueba este relleno. La longitud de los datos de texto no cifrado que se pueden cifrar con una llamada a CryptEncrypt con una clave RSA es la longitud del módulo de clave menos once bytes. Los once bytes son el mínimo elegido para el relleno PKCS #1. El texto cifrado se devuelve en formato little-endian .

Ejemplos

Para obtener ejemplos que usan esta función, vea Programa C de ejemplo: Cifrar un archivo y un programa C de ejemplo: descifrar un archivo.

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

CryptCreateHash

CryptDecrypt

CryptGenKey

CryptGetHashParam

CryptGetKeyParam

CryptImportKey

CryptMsgOpenToEncode

CryptSignHash

Funciones de cifrado y descifrado de datos