Função CryptGenKey (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 CryptGenKey gera uma chave de sessão criptográfica aleatória ou um par de chaves pública/privada. Um identificador para o par chave ou chave é retornado em phKey. Esse identificador pode ser usado conforme necessário com qualquer função CryptoAPI que exija um identificador de chave.

O aplicativo de chamada deve especificar o algoritmo ao chamar essa função. Como esse tipo de algoritmo é mantido agrupado com a chave, o aplicativo não precisa especificar o algoritmo posteriormente quando as operações criptográficas reais forem executadas.

Sintaxe

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

Parâmetros

[in] hProv

Um identificador para um provedor de serviços criptográficos (CSP) criado por uma chamada para CryptAcquireContext.

[in] Algid

Um valor ALG_ID que identifica o algoritmo para o qual a chave deve ser gerada. Os valores desse parâmetro variam dependendo do CSP usado.

Para ALG_ID valores a serem usados com o Provedor Criptográfico base da Microsoft, consulte Algoritmos de provedor base.

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

Para um CSP Diffie-Hellman, use um dos valores a seguir.

Valor Significado
CALG_DH_EPHEM
Especifica uma chave de Diffie-Hellman "Efêmera".
CALG_DH_SF
Especifica uma chave de Diffie-Hellman "Armazenar e Encaminhar".
 

Além de gerar chaves de sessão para algoritmos simétricos, essa função também pode gerar pares de chaves públicas/privadas. Cada cliente CryptoAPI geralmente possui dois pares de chaves públicas/privadas. Para gerar um desses pares de chaves, defina o parâmetro Argel como um dos valores a seguir.

Valor Significado
AT_KEYEXCHANGE
Troca de chaves
AT_SIGNATURE
Assinatura digital
 
Nota Quando as especificações de chave AT_KEYEXCHANGE e AT_SIGNATURE são especificadas, os identificadores de algoritmo usados para gerar a chave dependem do provedor usado. Como resultado, para essas especificações de chave, os valores retornados de CryptGetKeyParam (quando o parâmetro KP_ALGID é especificado) dependem do provedor usado. Para determinar qual identificador de algoritmo é usado pelos diferentes provedores para as especificações de chave AT_KEYEXCHANGE e AT_SIGNATURE, consulte ALG_ID.
 

[in] dwFlags

Especifica o tipo de chave gerada. Os tamanhos de uma chave de sessão, chave de assinatura RSA e chaves de troca de chaves RSA 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 assinatura RSA de 2.048 bits for gerada, o valor 0x08000000 será combinado com qualquer outro valor predefinido dwFlags com uma operação bit a bit OR . Os 16 bits superiores de 0x08000000 são 0x0800 ou decimal 2.048. O valor RSA1024BIT_KEY pode ser usado para especificar uma chave RSA de 1024 bits.

Devido à alteração das restrições de controle de exportação, o CSP padrão e o comprimento da chave padrão podem ser alterados 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.

Em particular, 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 e um comprimento de chave padrão de 1.024 bits para algoritmos de chave pública.

Se os 16 bits superiores forem zero, o tamanho da chave padrão será gerado. Se uma chave maior que o máximo ou menor que o mínimo for especificada, a chamada falhará com o código ERROR_INVALID_PARAMETER.

A tabela a seguir lista os comprimentos mínimo, padrão e máximo de assinatura e troca de chaves começando com o Windows XP.

Tipo de chave e provedor Comprimento mínimo Comprimento padrão Tamanho máximo
Provedor base RSA

Assinatura e ExchangeKeys

384 512 16.384
Provedores RSA fortes e aprimorados

Assinatura e Chaves do Exchange

384 1\.024 16.384
Provedores base DSS

Chaves de Assinatura

512 1\.024 1\.024
Provedores base DSS

Chaves do Exchange

Não aplicável Não aplicável Não aplicável
Provedores de base DSS/DH

Chaves de Assinatura

512 1\.024 1\.024
Provedores de base DSS/DH

Chaves do Exchange

512 512 1\.024
Provedores avançados de DSS/DH

Chaves de Assinatura

512 1\.024 1\.024
Provedores avançados de DSS/DH

Chaves do Exchange

512 1\.024 4\.096
 

Para obter comprimentos de chave de sessão, consulte CryptDeriveKey.

Para obter mais informações sobre chaves geradas usando provedores da Microsoft, consulte Provedores de Serviços Criptográficos da Microsoft.

Os 16 bits inferiores desse parâmetro podem ser zero ou uma combinação de um ou mais dos valores a seguir.

Valor Significado
CRYPT_ARCHIVABLE
Se esse sinalizador estiver definido, a chave poderá ser exportada até que seu identificador seja fechado por uma chamada para CryptDestroyKey. Isso permite que chaves recém-geradas sejam exportadas após a criação para arquivamento ou recuperação de chave. Depois que o identificador é fechado, a chave não é mais exportável.
CRYPT_CREATE_IV
Esse sinalizador não é usado.
CRYPT_CREATE_SALT
Se esse sinalizador for definido, a chave será atribuída automaticamente a um valor de sal aleatório. 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 (por meio de CryptExportKey), o valor de sal também deve ser obtido e mantido com a chave BLOB.

CRYPT_DATA_KEY
Esse sinalizador não é usado.
CRYPT_EXPORTABLE
Se esse sinalizador estiver definido, a chave poderá ser transferida do CSP para um BLOB de chave usando a função CryptExportKey . Como as chaves de sessão geralmente devem ser exportáveis, esse sinalizador geralmente deve ser definido quando são criadas.

Se esse sinalizador não estiver definido, a chave não será exportável. Para uma chave de sessão, isso significa que a chave só está disponível dentro da sessão atual e apenas o aplicativo que a criou poderá usá-la. Para um par de chaves pública/privada, isso significa que a chave privada não pode ser transportada ou apoiada.

Esse sinalizador se aplica somente a BLOBs de chave de sessão e de chave privada. Ele não se aplica a chaves públicas, que são sempre exportáveis.

CRYPT_FORCE_KEY_PROTECTION_HIGH
Esse sinalizador especifica uma proteção de chave forte. Quando esse sinalizador é definido, o usuário é solicitado a inserir uma senha para a chave quando a chave é criada. O usuário será solicitado a inserir a senha sempre que essa chave for usada.

Esse sinalizador só é usado pelos CSPs fornecidos pela Microsoft. CSPs de terceiros definirão seu próprio comportamento para proteção de chave forte.

Especificar esse sinalizador causa o mesmo resultado de chamar essa função com o sinalizador CRYPT_USER_PROTECTED quando a proteção de chave forte é especificada no registro do sistema.

Se esse sinalizador for especificado e o identificador do provedor no parâmetro hProv tiver sido criado usando o sinalizador CRYPT_VERIFYCONTEXT ou CRYPT_SILENT , essa função definirá o último erro como NTE_SILENT_CONTEXT e retornará zero.

Windows Server 2003 e Windows XP: Não há suporte para esse sinalizador.

CRYPT_KEK
Esse sinalizador não é usado.
CRYPT_INITIATOR
Esse sinalizador não é usado.
CRYPT_NO_SALT
Esse sinalizador especifica que um valor sem sal é alocado para uma chave simétrica de quarenta bits. Para obter mais informações, confira Funcionalidade de valor de sal.
CRYPT_ONLINE
Esse sinalizador não é usado.
CRYPT_PREGEN
Esse sinalizador especifica uma geração inicial de chave Diffie-Hellman ou DSS. Esse sinalizador é útil apenas com CSPs de Diffie-Hellman e DSS. Quando usado, um comprimento de chave padrão será usado, a menos que um comprimento de chave seja especificado nos 16 bits superiores do parâmetro dwFlags . Se os parâmetros que envolvem comprimentos de chave forem definidos em uma chave PREGEN Diffie-Hellman ou DSS usando CryptSetKeyParam, os comprimentos de chave deverão ser compatíveis com o comprimento da chave definido aqui.
CRYPT_RECIPIENT
Esse sinalizador não é usado.
CRYPT_SF
Esse sinalizador não é usado.
CRYPT_SGCKEY
Esse sinalizador não é usado.
CRYPT_USER_PROTECTED
Se esse sinalizador estiver definido, o usuário será notificado por meio de uma caixa de diálogo ou de outro método quando determinadas ações estiverem tentando usar essa chave. O comportamento preciso é especificado pelo CSP que está sendo usado. Se o contexto do provedor foi aberto com o sinalizador CRYPT_SILENT definido, usar esse sinalizador causará uma falha e o último erro será definido como NTE_SILENT_CONTEXT.
CRYPT_VOLATILE
Esse sinalizador não é usado.

[out] phKey

Endereço para o qual a função copia o identificador da chave recém-gerada. Quando terminar de usar a chave, exclua o identificador para a chave chamando a função CryptDestroyKey .

Retornar valor

Retornará diferente de zero se tiver êxito ou zero caso contrário.

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_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

Se as chaves forem geradas para criptografias de blocosimétrico, a chave, por padrão, será 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 .

Para escolher um comprimento de chave apropriado, os seguintes métodos são recomendados:

  • Enumerar os algoritmos aos quais o CSP dá suporte e obter comprimentos máximos e mínimos de chave para cada algoritmo. Para fazer isso, 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.

Exemplos

O exemplo a seguir mostra a criação de uma chave de sessão aleatória. Para obter um exemplo que inclui o contexto completo para este exemplo, consulte Exemplo de Programa C: Criptografando um arquivo. Para obter outro exemplo que usa essa função, consulte Exemplo de programa C: descriptografando um arquivo.

//-------------------------------------------------------------------
//  Declare the handle to the key.
HCRYPTKEY hKey; 
//-------------------------------------------------------------------
//  This example assumes that a cryptographic context 
//  has been acquired, and that it is stored in hCryptProv.
//---------------------------------------------------------------
//  Create a random session key. 

 if(CryptGenKey(
          hCryptProv, 
          ENCRYPT_ALGORITHM, 
          KEYLENGTH | CRYPT_EXPORTABLE, 
          &hKey))
 {
         printf("A session key has been created.\n");
 } 
 else
 {
          printf("Error during CryptGenKey.\n"); 
          exit(1);
 }
//-------------------------------------------------------------------
//  The key created can be exported into a key BLOB that can be
//  written to a file.
//  ...
//  When you have finished using the key, free the resource.
if (!CryptDestroyKey(hKey))
{
          printf("Error during CryptDestroyKey.\n"); 
          exit(1);
}

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

Cryptdestroykey

Cryptexportkey

Cryptgetkeyparam

Cryptimportkey

Cryptsetkeyparam

Funções de Geração de Chaves e Exchange

Problemas de threading com provedores de serviços criptográficos