Compartilhar via


Função CryptDeriveKey (wincrypt.h)

Importante essa API foi preterida. O software novo e existente deve começar a usar APIs de Próxima Geração da Criptografia. Microsoft pode remover essa API em versões futuras.
 
A função CryptDeriveKey gera chaves de sessão de criptográficas derivadas de um valor de dados base. Essa função garante que, quando o mesmo provedor de serviços criptográficos (CSP) e algoritmos são usados, as chaves geradas a partir dos mesmos dados base sã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úblicos/privados.

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 aprimorados.

[in] hBaseData

Um identificador para um objeto de 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 outra dwFlags valor predefinido com uma operação deOR bit a bit. Devido à alteração das restrições de controle de exportação, o CSP padrão e o padrão comprimento da chave 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 debit a bit para combiná-los.

Valor Significado
CRYPT_CREATE_SALT
Normalmente, quando uma chave de sessão é feita de um valor hash, há uma série de 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 estiver 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 não zero são exportadas (usando CryptExportKey), o valor de sal também deve ser obtido e mantido com a chave blob.

CRYPT_EXPORTABLE
Se esse sinalizador estiver 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 só está disponível 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 de sal sem é alocado para uma chave simétrica de 40 bits. Para obter mais informações, consulte de 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 devem ser chamados 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 somente com provedores de do 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, libere o identificador chamando a função CryptDestroyKey.

Valor de retorno

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 de 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.

Observações

Quando as chaves são geradas para codificações de bloco simétricas, a chave, por padrão, é configurada no modo CBC ( de encadeamento de blocos de criptografia) com um vetor de inicialização 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 ode hash . Depois que CryptDeriveKey tiver sido chamado, não será possível adicionar mais dados ao hash. As chamadas adicionais para CryptHashData ou CryptHashSessionKey falhar. Depois que o aplicativo for concluído com o hash, CryptDestroyHash deverá ser chamado para destruir o objeto hash.

Para escolher umade comprimento de chave apropriada, 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 é a primeira 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. Deixe k ser o comprimento do valor de hash representado pelo parâmetro de entrada hBaseData. Defina o primeiro k bytes do buffer como resultado de uma operação de XOR do primeiro 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 o primeiro k bytes do buffer como resultado de uma operação de XOR do primeiro k bytes do buffer com o valor de hash representado pelo parâmetro de entrada hBaseData.
  3. Hash do resultado da etapa 1 usando o mesmo algoritmo de hash usado para calcular o valor de hash representado pelo parâmetro hBaseData.
  4. Hash do resultado da etapa 2 usando o mesmo algoritmo de hash usado para calcular o valor de hash representado pelo parâmetro hBaseData.
  5. Concatena o resultado da etapa 3 com o resultado da etapa 4.
  6. Use o primeiro n bytes do resultado da etapa 5 como a chave derivada.
O provedor de serviços criptográficos RSA completo 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 de criptografia Diffie-Hellman DSS avançado da Microsoft. 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 comprimentos mínimos, padrão e máximos de chave 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 umde senha.

Requisitos

Requisito Valor
de cliente com suporte mínimo Windows XP [somente aplicativos da área de trabalho]
servidor com suporte mínimo Windows Server 2003 [somente aplicativos da área de trabalho]
da Plataforma de Destino Windows
cabeçalho wincrypt.h
biblioteca Advapi32.lib
de DLL Advapi32.dll

Consulte também

CryptAcquireContext

CryptCreateHash

CryptDestroyHash

CryptDestroyKey

CryptExportKey

CryptGenKey

CryptGetKeyParam

CryptHashData

CryptHashSessionKey

CryptSetKeyParam

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