Descriptografia das confirmações de preço

Quando seu anúncio ganha um leilão, o Google pode informar qual foi o preço vencedor, caso o snippet HTML que define o anúncio inclua a macro WINNING_PRICE. O Google retorna o preço vencedor na forma criptografada. Os tópicos a seguir explicam como seu aplicativo pode descriptografar as informações do preço vencedor.

  1. Cenário
  2. Dependências
  3. Código de exemplo
  4. Esquema de criptografia
  5. Esquema de descriptografia
  6. Detecção de ataques de resposta desatualizada

Cenário

  1. Seu aplicativo inclui a macro WINNING_PRICE no snippet HTML que ele retorna para o Google.
  2. O Google substitui o preço vencedor pela macro, em uma codificação com base64 segura para a Web e sem preenchimento (RFC 3548).
  3. O snippet passa a confirmação no formato que você escolheu. Por exemplo, a confirmação pode ser passada no URL de uma solicitação de pixel invisível renderizada como parte do anúncio.
  4. No servidor, seu aplicativo decodifica com base64 as informações do preço vencedor e descriptografa o resultado.

Dependências

Você precisará de uma biblioteca de criptografia compatível com SHA-1 HMAC, como Openssl.

Código de exemplo

O código de exemplo é fornecido em Java e C++ e seu download pode ser feito em http://code.google.com/p/privatedatacommunicationprotocol.

  • O código de exemplo em Java usa o decodificador base64 do Projeto Apache commons. Você não precisará fazer o download do código do Apache commons, porque a implementação de referência inclui a parte necessária e, assim, já está contida.

  • O código de exemplo em C++ usa o método OpenSSL base64 BIO. Ele usa uma string codificada com base64 segura para a Web (RFC 3548) e a decodifica. Normalmente, strings com base base64 segura para a Web substituem o preenchimento "=" por "." (as aspas foram adicionadas para uma leitura mais fácil e não estão incluídas no protocolo), mas a substituição da macro não preenche o preço criptografado. A implementação de referência adiciona o preenchimento porque OpenSSL tem problemas com strings sem preenchimento.

Voltar ao início

Esquema de criptografia

O preço é criptografado usando um esquema de criptografia personalizado projetado para minimizar a sobrecarga do tamanho ao mesmo tempo em que assegura a segurança adequada. O esquema de criptografia usa um algoritmo de chave HMAC para gerar um preenchimento secreto com base no ID do evento de impressão exclusivo.

O preço criptografado tem um comprimento fixo de 28 bytes. Ele é formado por um vetor de inicialização de 16 bytes, 8 bytes de texto cifrado e uma assinatura de integridade de 4 bytes. O preço criptografado é codificado em base64 seguro para a web, segundo a RFC 3548, com caracteres de preenchimento omitidos. Por isso, o preço criptografado de 28 bytes é codificado como uma string base-64 segura para a Web de 38 caracteres.

O formato criptografado é:

        {initialization_vector (16 bytes)}{encrypted_price (8 bytes)}
        
        {integrity (4 bytes)}

Como o preço é criptografado como <price xor HMAC(encryption_key, initialization_vector)> a descriptografia calcula HMAC(encryption_key,initialization_vector) e xor com o preço criptografado para reverter a criptografia. O estágio de integridade usa 4 bytes de <HMAC(integrity_key, price||initialization_vector)> em que || é concatenação.

Entradas

iv vetor de inicialização (16 bytes - exclusivo da impressão)
e_key chave de criptografia (32 bytes - fornecida durante a configuração da conta)
i_key chave de integridade (32 bytes - fornecida durante a configuração da conta)
price (8 bytes - em micros da moeda da conta)

Notação

hmac(k, d) SHA-1 HMAC de dados d, usando chave k.
a || b string a concatenada com string b

Pseudocódigo

pad = hmac(e_key, iv)  // first 8 bytes
enc_price = pad <xor> price
signature = hmac(i_key, price || iv)  // first 4 bytes

final_message = WebSafeBase64Encode( iv || enc_price || signature )

Voltar ao início

Esquema de descriptografia

Seu código de descriptografia deve descriptografar o preço usando a chave de criptografia e verificar os bits de integridade com a chave de integridade. As chaves serão fornecidas para você durante a configuração. Não há nenhuma restrição nos detalhes quanto à maneira como você estrutura sua implementação. Para a maior parte, você deve ser capaz de usar o código de exemplo e adaptá-lo de acordo com suas necessidades.

Entradas

e_key chave de criptografia, 32 bytes - fornecida durante a configuração da conta
i_key chave de integridade, 32 bytes - fornecida durante a configuração da conta
final_message codificada com base64 segura para a Web de 38 caracteres

Pseudocódigo

enc_price = WebSafeBase64Decode(final_message)

(iv, p, sig) = dec_price -- split up according to fixed lengths
price_pad = hmac(e_key, iv)
price = p <xor> price_pad
conf_sig = hmac(i_key, price || iv)
success = (conf_sig == sig)

Voltar ao início

Detecção de ataques de resposta desatualizada

Para detectar uma resposta desatualizada, ou repetição, ataques, é recomendável filtrar respostas com uma marca de data e hora que seja diferente da hora do sistema, depois de levar em conta as diferenças de fuso horário.

O vetor de inicialização contém uma marca de data e hora nos primeiros 8 bytes. Ele pode ser lido pela seguinte função C++:

void GetTime(const char* iv, struct timeval* tv) {
    
    uint32 val;
    
    memcpy(&val, iv, sizeof(val));
    tv->tv_sec = htonl(val);
    memcpy(&val, iv+sizeof(val), sizeof(val));
    tv->tv_usec = htonl(val)
}

A marca de data e hora pode ser convertida em uma forma legível por humanos usando o seguinte código em C++:

struct tm tm;
localtime_r(&tv->tv_sec, &tm);

printf("%04d-%02d-%02d|%02d:%02d:%02d.%06ld",

    tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
    
    tm.tm_hour, tm.tm_min, tm.tm_sec,
    tv_.tv_usec);

Voltar ao início

 

Enviar comentários sobre…

DoubleClick Ad Exchange Real-Time Bidding Protocol