Função CryptDeriveKey (wincrypt.h)

Importante Essa API foi preterida. O software novo e existente deve começar a usar APIs de Criptografia de Próxima Geração. A Microsoft pode remover essa API em versões futuras.
 
A função CryptDeriveKey gera chaves de sessão criptográficas derivadas de um valor de dados base. Essa função garante que, quando os mesmos CSP ( provedor de serviços criptográficos ) e algoritmos forem usados, as chaves geradas a partir dos mesmos dados base serão idênticas. Os dados base podem ser uma senha ou qualquer outro dado do usuário.

Essa função é a mesma que CryptGenKey, exceto que as chaves de sessão geradas são derivadas de dados base em vez de serem aleatórias. CryptDeriveKey só pode ser usado para gerar chaves de sessão. Ele não pode gerar pares de chaves públicas/privadas.

Um identificador para a chave de sessão é retornado no parâmetro phKey . Esse identificador pode ser usado com qualquer função CryptoAPI que exija um identificador de chave.

Sintaxe

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

Parâmetros

[in] hProv

Um identificador HCRYPTPROV de um CSP criado por uma chamada para CryptAcquireContext.

[in] Algid

Uma estrutura ALG_ID que identifica o algoritmo de criptografia simétrica para o qual a chave deve ser gerada. Os algoritmos disponíveis provavelmente serão diferentes para cada CSP. Para obter mais informações sobre qual identificador de algoritmo é usado pelos diferentes provedores para as especificações de chave AT_KEYEXCHANGE e AT_SIGNATURE, consulte ALG_ID.

Para obter mais informações sobre ALG_ID valores a serem usados com o Provedor Criptográfico base da Microsoft, consulte Algoritmos de provedor base. Para obter mais informações sobre ALG_ID valores a serem usados com o Provedor Criptográfico Forte da Microsoft ou o Provedor criptográfico avançado da Microsoft, consulte Algoritmos de provedor avançado.

[in] hBaseData

Um identificador para um objeto hash que foi alimentado com os dados base exatos.

Para obter esse identificador, um aplicativo deve primeiro criar um objeto hash com CryptCreateHash e, em seguida, adicionar os dados base ao objeto hash com CryptHashData. Esse processo é descrito em detalhes em Hashes e Assinaturas Digitais.

[in] dwFlags

Especifica o tipo de chave gerada.

Os tamanhos de uma chave de sessão podem ser definidos quando a chave é gerada. O tamanho da chave, que representa o comprimento do módulo de chave em bits, é definido com os 16 bits superiores desse parâmetro. Portanto, se uma chave de sessão RC4 de 128 bits for gerada, o valor 0x00800000 será combinado com qualquer outro valor predefinido dwFlags com uma operação bit a bit OR . Devido à alteração das restrições de controle de exportação, o CSP padrão e o comprimento da chave padrão podem mudar entre as versões do sistema operacional. É importante que a criptografia e a descriptografia usem o mesmo CSP e que o comprimento da chave seja definido explicitamente usando o parâmetro dwFlags para garantir a interoperabilidade em diferentes plataformas do sistema operacional.

Os 16 bits inferiores desse parâmetro podem ser zero ou você pode especificar um ou mais dos sinalizadores a seguir usando o operador OR bit a bit para combiná-los.

Valor Significado
CRYPT_CREATE_SALT
Normalmente, quando uma chave de sessão é feita com base em um valor de hash , há vários bits restantes. Por exemplo, se o valor de hash for de 128 bits e a chave de sessão for de 40 bits, haverá 88 bits restantes.

Se esse sinalizador for definido, a chave será atribuída a um valor de sal com base nos bits de valor de hash não utilizados. Você pode recuperar esse valor de sal usando a função CryptGetKeyParam com o parâmetro dwParam definido como KP_SALT.

Se esse sinalizador não estiver definido, a chave recebe um valor de sal zero.

Quando as chaves com valores de sal diferente de zero são exportadas (usando CryptExportKey), o valor de sal também deve ser obtido e mantido com o BLOB de chave.

CRYPT_EXPORTABLE
Se esse sinalizador for definido, a chave de sessão poderá ser transferida do CSP para um BLOB de chave por meio da função CryptExportKey . Como as chaves geralmente devem ser exportáveis, esse sinalizador geralmente deve ser definido.

Se esse sinalizador não estiver definido, a chave de sessão não será exportável. Isso significa que a chave está disponível somente na sessão atual e apenas o aplicativo que a criou é capaz de usá-la.

Esse sinalizador não se aplica a pares de chaves públicas/privadas.

CRYPT_NO_SALT
Esse sinalizador especifica que um valor sem sal é alocado para uma chave simétrica de 40 bits. Para obter mais informações, confira Funcionalidade de valor de sal.
CRYPT_UPDATE_KEY
Alguns CSPs usam chaves de sessão derivadas de vários valores de hash. Quando esse for o caso, CryptDeriveKey deve ser chamado várias vezes.

Se esse sinalizador estiver definido, uma nova chave de sessão não será gerada. Em vez disso, a chave especificada por phKey é modificada. O comportamento preciso desse sinalizador depende do tipo de chave que está sendo gerada e do CSP específico que está sendo usado.

Os provedores de serviços criptográficos da Microsoft ignoram esse sinalizador.

CRYPT_SERVER
1024 (0x400)
Esse sinalizador é usado apenas com provedores Schannel . Se esse sinalizador estiver definido, a chave a ser gerada será uma chave de gravação do servidor; caso contrário, é uma chave de gravação do cliente.

[in, out] phKey

Um ponteiro para uma variável HCRYPTKEY para receber o endereço do identificador da chave recém-gerada. Quando terminar de usar a chave, solte o identificador chamando a função CryptDestroyKey .

Retornar valor

Se a função for bem-sucedida, a função retornará diferente de zero (TRUE).

Se a função falhar, ela retornará zero (FALSE). Para obter informações de erro estendidas, chame GetLastError.

Os códigos de erro precedidos por "NTE" são gerados pelo CSP específico que está sendo usado. Alguns códigos de erro possíveis são listados na tabela a seguir.

Código de retorno Descrição
ERROR_INVALID_HANDLE
Um dos parâmetros especifica um identificador que não é válido.
ERROR_INVALID_PARAMETER
Um dos parâmetros contém um valor que não é válido. Isso geralmente é um ponteiro que não é válido.
NTE_BAD_ALGID
O parâmetro Argel especifica um algoritmo que esse CSP não dá suporte.
NTE_BAD_FLAGS
O parâmetro dwFlags contém um valor que não é válido.
NTE_BAD_HASH
O parâmetro hBaseData não contém um identificador válido para um objeto hash.
NTE_BAD_HASH_STATE
Foi feita uma tentativa de adicionar dados a um objeto hash que já está marcado como "concluído".
NTE_BAD_UID
O parâmetro hProv não contém um identificador de contexto válido.
NTE_FAIL
A função falhou de alguma forma inesperada.
NTE_SILENT_CONTEXT
O provedor não pôde executar a ação porque o contexto foi adquirido como silencioso.

Comentários

Quando as chaves são geradas para codificações de blocosimétrico, a chave, por padrão, é configurada no modo CBC (encadeamento de blocos de criptografia) com um vetor de inicialização igual a zero. Esse modo de criptografia fornece um bom método padrão para criptografar dados em massa. Para alterar esses parâmetros, use a função CryptSetKeyParam .

A função CryptDeriveKey conclui o hash. Depois que CryptDeriveKey tiver sido chamado, mais dados não poderão ser adicionados ao hash. Chamadas adicionais para CryptHashData ou CryptHashSessionKey falham. Depois que o aplicativo for feito com o hash, CryptDestroyHash deverá ser chamado para destruir o objeto hash.

Para escolher um comprimento de chave apropriado, os métodos a seguir são recomendados.

  • Para enumerar os algoritmos aos quais o CSP dá suporte e obter comprimentos máximos e mínimos de chave para cada algoritmo, chame CryptGetProvParam com PP_ENUMALGS_EX.
  • Use os comprimentos mínimo e máximo para escolher um comprimento de chave apropriado. Nem sempre é aconselhável escolher o comprimento máximo porque isso pode levar a problemas de desempenho.
  • Depois que o comprimento da chave desejado tiver sido escolhido, use os 16 bits superiores do parâmetro dwFlags para especificar o comprimento da chave.
Deixe n ser o comprimento da chave derivada necessário, em bytes. A chave derivada é o primeiro n bytes do valor de hash após a computação de hash ter sido concluída por CryptDeriveKey. Se o hash não for um membro da família SHA-2 e a chave necessária for para 3DES ou AES, a chave será derivada da seguinte maneira:
  1. Forme um buffer de 64 bytes repetindo a constante 0x36 64 vezes. Let k be the length of the hash value that is represented by the input parameter hBaseData. Defina os primeiros k bytes do buffer como o resultado de uma operação XOR dos primeiros k bytes do buffer com o valor de hash representado pelo parâmetro de entrada hBaseData.
  2. Forme um buffer de 64 bytes repetindo a constante 0x5C 64 vezes. Defina os primeiros k bytes do buffer como o resultado de uma operação XOR dos primeiros k bytes do buffer com o valor de hash representado pelo parâmetro de entrada hBaseData.
  3. Hash o resultado da etapa 1 usando o mesmo algoritmo de hash usado para calcular o valor de hash representado pelo parâmetro hBaseData .
  4. Hash o resultado da etapa 2 usando o mesmo algoritmo de hash usado para calcular o valor de hash representado pelo parâmetro hBaseData .
  5. Concatene o resultado da etapa 3 com o resultado da etapa 4.
  6. Use os primeiros n bytes do resultado da etapa 5 como a chave derivada.
O provedor de serviços criptográficos completo RSA padrão é o provedor criptográfico forte do Microsoft RSA. A assinatura DSS padrão Diffie-Hellman provedor de serviços criptográficos é o Provedor criptográfico de Diffie-Hellman do Microsoft Enhanced DSS. Cada um desses CSPs tem um comprimento de chave simétrica padrão de 128 bits para RC2 e RC4.

A tabela a seguir lista os comprimentos de chave mínimo, padrão e máximo para chave de sessão por algoritmo e provedor.

Provedor Algoritmos Comprimento mínimo da chave Comprimento da chave padrão Comprimento máximo da chave
MS Base RC4 e RC2 40 40 56
MS Base DES 56 56 56
MS Avançado RC4 e RC2 40 128 128
MS Avançado DES 56 56 56
MS Avançado 3DES 112 112 112 112
MS Avançado 3DES 168 168 168
MS Strong RC4 e 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 e RC2 40 40 56
DSS/DH Base Cylink MEK 40 40 40
DSS/DH Base DES 56 56 56
DSS/DH Enh RC4 e 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
 

Exemplos

Para obter um exemplo que usa essa função, consulte Exemplo de programa C: derivando uma chave de sessão de uma senha.

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows XP [somente aplicativos da área de trabalho]
Servidor mínimo com suporte Windows Server 2003 [somente aplicativos da área de trabalho]
Plataforma de Destino Windows
Cabeçalho wincrypt.h
Biblioteca Advapi32.lib
DLL Advapi32.dll

Confira também

Cryptacquirecontext

Cryptcreatehash

Cryptdestroyhash

Cryptdestroykey

Cryptexportkey

Cryptgenkey

Cryptgetkeyparam

Crypthashdata

Crypthashsessionkey

Cryptsetkeyparam

Geração de chaves e funções do Exchange