Compartilhar via


Verificar se o sistema dá suporte a um método de hash

Este tópico descreve como verificar se o sistema dá suporte a um método de hash.

As Assinaturas Digitais XPS usam a API de Criptografia, que fornece métodos para verificar se o sistema dá suporte a um método de hash específico. Para usar a função CryptXmlEnumAlgorithmInfo da API de Criptografia para enumerar os métodos de hash compatíveis com o sistema, o chamador deve fornecer um método de retorno de chamada e uma estrutura de dados. A função CryptXmlEnumAlgorithmInfo passa os dados de enumeração de volta para o chamador por meio do método de retorno de chamada.

A estrutura de dados usada neste exemplo é mostrada no exemplo de código a seguir e contém os seguintes campos:

Campo Descrição
userDigestAlgorithm Um campo LPWSTR que aponta para a cadeia de caracteres que contém o URI do algoritmo de hash a ser verificado.
userDigestAlgorithmSupported Um valor Booliano que indica se o algoritmo de hash é compatível com o certificado.

 

struct DigestMethodData
{
    LPCWSTR userDigestAlgorithm; 
    BOOL    userDigestAlgorithmSupported;
};

O método de API de Criptografia que enumera os métodos de hash usa um método de retorno de chamada para retornar dados ao chamador. O CryptXmlEnumAlgorithmInfo enumera os métodos de hash compatíveis com o sistema e chama o método de retorno de chamada para cada método de hash que ele enumera, até que o método de retorno de chamada retorne FALSE ou até que todos os métodos de hash compatíveis com o sistema sejam enumerados. O método de retorno de chamada neste exemplo compara o método de hash que é passado por CryptXmlEnumAlgorithmInfo com o método de hash fornecido pelo método de chamada.

BOOL WINAPI 
EnumDigestMethodCallback (
    __in   const CRYPT_XML_ALGORITHM_INFO *certMethodInfo,
    __inout_opt  void                     *userArg
)
{
    // MAX_ALG_ID_LEN is used to set the maximum length of the 
    // algorithm URI in the string comparison. The URI is not 
    // likely to be longer than 128 characters so a fixed-size
    // buffer is used in this example.
    // To make this function more robust, consider
    // setting this value dynamically.
    static const  size_t MAX_ALG_ID_LEN = 128;
    DigestMethodData   *certificateAlgorithmData = 
        (DigestMethodData*)userArg;

    if (NULL != userArg) {
        // Assign user data to local data structure
        certificateAlgorithmData = (DigestMethodData*)userArg;
    } else {
        // Unable to continue this enumeration without 
        //  data from calling method.
        return FALSE;
    }
    
    // For each algorithm in the enumeration, check to see 
    //  if the URI of the current supported algorithm matches 
    //  the URI passed in userArg.
    int cmpResult = 0;
    cmpResult = wcsncmp( 
        certMethodInfo->wszAlgorithmURI, 
        certificateAlgorithmData->userDigestAlgorithm, 
        MAX_ALG_ID_LEN );

    if ( 0 == cmpResult )
    {
        // This is a match...
        //  set supported value to true
        certificateAlgorithmData->userDigestAlgorithmSupported = TRUE;
        //  ...and return FALSE to stop any further enumeration
        return FALSE;
    } 
    else
    {
        // no match was found
        // return TRUE to continue enumeration
        return TRUE;
    }
}

O exemplo de código a seguir encapsula a funcionalidade de validação em um único método, que retorna um valor Booliano que indica se o sistema dá suporte ao método de hash.

BOOL 
SupportsDigestAlgorithm (
    __in LPCWSTR digestMethodToCheck
)
{
    HRESULT  hr = S_OK;

    // Initialize the structure that will hold information about the 
    //  digest method to check
    DigestMethodData  certificateAlgorithmData;

    certificateAlgorithmData.userDigestAlgorithmSupported = FALSE;
    certificateAlgorithmData.userDigestAlgorithm = digestMethodToCheck;

    // Enumerate the algorithms that are supported on the system, 
    //  the callback method compares each supported algorithm to the one
    //  passed in digestMethodToCheck and returns true in the
    //  certificateAlgorithmData.userDigestAlgorithmSupported field if
    //  the provided digest algorithm is supported by system.
    //
    // Note that CRYPT_XML_GROUP_ID_HASH is set to enumerate 
    //  digest methods
    hr = CryptXmlEnumAlgorithmInfo(
        CRYPT_XML_GROUP_ID_HASH,       // NOTE: CRYPT_XML_GROUP_ID_HASH
        CRYPT_XML_FLAG_DISABLE_EXTENSIONS,
        (void*)&certificateAlgorithmData,
        EnumDigestMethodCallback);

    return certificateAlgorithmData.userDigestAlgorithmSupported;
}

Próximas Etapas 

Carregar um certificado de um arquivo

Verificar se um certificado dá suporte a um método de assinatura

Inserir cadeias de certificados em um documento

Usado neste exemplo

CryptXmlEnumAlgorithmInfo

Para obter mais informações

API de Criptografia

Funções de criptografia

Erros de API de Assinatura Digital do XPS

Erros de documento XPS

XML Paper Specification