Verifique se o sistema suporta um método Digest

Este tópico descreve como verificar se o sistema suporta um método de resumo.

As assinaturas digitais XPS usam a API de criptografia, que fornece métodos para verificar se o sistema suporta um método de resumo específico. Para usar a função CryptXmlEnumAlgorithmInfo da Crypto API para enumerar os métodos de resumo suportados pelo 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
algoritmoDeDigestaoDoUtilizador Um campo LPWSTR que aponta para a cadeia de caracteres que contém o URI do algoritmo digest a ser verificado.
algoritmoDeResumoDoUtilizadorSuportado Um valor booleano que indica se o algoritmo de resumo é suportado pelo certificado.

 

struct DigestMethodData
{
    LPCWSTR userDigestAlgorithm; 
    BOOL    userDigestAlgorithmSupported;
};

O método Crypto API que enumera os métodos de resumo usa uma função de retorno de chamada para devolver dados ao cliente. CryptXmlEnumAlgorithmInfo enumera os métodos digest suportados pelo sistema e chama o método de retorno de chamada para cada método digest que enumera, até que o método de retorno de chamada retorne FALSE ou até que todos os métodos de resumo suportados pelo sistema sejam enumerados. O método callback neste exemplo compara o método digest que é passado pelo CryptXmlEnumAlgorithmInfo com o método digest 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 num único método, que retorna um valor Boolean que indica se o sistema oferece suporte ao método Digest.

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óximos passos

carregar um certificado de um arquivo

verificar se um certificado suporta um método de assinatura

incorporar cadeias de certificados em um documento

usados neste exemplo

CryptXmlEnumAlgorithmInfo

Para mais informações

API de criptografia

Funções de criptografia

Erros de API de assinatura digital XPS

Erros de documento XPS

Especificação de Papel XML