Si los publicadores pasan datos de ubicación móvil a Authorized Buyers, que es más específico que un código postal, Authorized Buyers enviará un geovallado hiperlocal a los compradores en un nuevo campo encriptado: BidRequest.encrypted_hyperlocal_set
.
Rutas
- Un usuario instala una app para dispositivos móviles compatible con anuncios y da su consentimiento para que esta acceda a la ubicación del dispositivo y la comparta con terceros. Esta aplicación también está integrada con el SDK de anuncios de Google y envía la ubicación de este dispositivo a Google.
- Los servidores de Google generan una señal de orientación hiperlocal especial que representa un geovallado que rodea la ubicación del dispositivo, por ejemplo, para proteger la privacidad del usuario.
- Los servidores de Google serializan y encriptan la señal de orientación hiperlocal con la llave de seguridad específica de cada comprador. Ten en cuenta que tu ofertante se basa en la misma clave para desencriptar la macro WINNING_PRICE.
- Su ofertante desencripta y deserializa la señal de orientación hiperlocal en un búfer de protocolo. Luego, su ofertante puede analizar el indicador y realizar una oferta según corresponda.
Dependencias
Necesitarás una biblioteca criptográfica que admita SHA-1 HMAC, como Openssl.
Definición
En el proto, se define una señal de orientación hiperlocal de la siguiente manera:
// A hyperlocal targeting location when available. // message Hyperlocal { // A location on the Earth's surface. // message Point { optional float latitude = 1; optional float longitude = 2; } // The mobile device can be at any point inside the geofence polygon defined // by a list of corners. Currently, the polygon is always a parallelogram // with 4 corners. repeated Point corners = 1; } message HyperlocalSet { // This field currently contains at most one hyperlocal polygon. repeated Hyperlocal hyperlocal = 1; // The approximate geometric center of the geofence area. It is calculated // exclusively based on the geometric shape of the geofence area and in no // way indicates the mobile device's actual location within the geofence // area. If multiple hyperlocal polygons are specified above then // center_point is the geometric center of all hyperlocal polygons. optional Hyperlocal.Point center_point = 2; } // Hyperlocal targeting signal when available, encrypted as described at // https://developers.google.com/authorized-buyers/rtb/response-guide/decrypt-hyperlocal optional bytes encrypted_hyperlocal_set = 40;
Cada señal de orientación hiperlocal contiene uno o más polígonos y un punto central. Para cada polígono, el indicador de orientación hiperlocal contiene:
- La latitud y la longitud de cada esquina del polígono de forma secuencial, que se pasan como un campo
corners
repetido. - El centro geométrico aproximado del área de geovallado, que se pasa en el campo opcional
center_point
.
Estructura del indicador de segmentación
El indicador de segmentación hiperlocal encriptado que se incluye en BidRequest.encrypted_hyperlocal_set
contiene 3 secciones:
initialization_vector
: 16 bytesciphertext
: Serie de secciones de 20 bytes.integrity_signature
: 4 bytes
{initialization_vector (16 bytes)}{ciphertext (20-byte sections)}{integrity_signature (4 bytes)}
El arreglo de bytes ciphertext
se divide en varias secciones de 20 bytes, con la excepción de que la última sección puede contener entre 1 y 20 bytes inclusive. Para cada sección del byte_array
original, el ciphertext
de 20 bytes correspondiente se genera de la siguiente manera:
<byte_array <xor> HMAC(encryption_key, initialization_vector || counter_bytes)>
Donde ||
es la concatenación.
Definiciones
Variable | Detalles |
---|---|
initialization_vector |
16 bytes: único para la impresión |
encryption_key |
32 bytes: Se proporcionan en la configuración de la cuenta. |
integrity_key |
32 bytes: Se proporcionan en la configuración de la cuenta. |
byte_array |
Un objeto HyperlocalSet serializado, en secciones de 20 bytes. |
counter_bytes |
Valor en bytes que muestra el número ordinal de la sección, consulta a continuación. |
final_message |
El arreglo de bytes que se envió a través del campo BidRequest.encrypted_hyperlocal_set . |
Operadores | Detalles |
---|---|
hmac(key, data) |
SHA-1 HMAC, que usa key para encriptar data |
a || b |
La string a se concatena con la string b . |
Calcular contador_bytes
counter_bytes
marca el orden de cada sección de 20 bytes de ciphertext
. Ten en cuenta que la última sección puede contener entre 1 y 20 bytes inclusive. Para completar counter_bytes
con el valor correcto cuando ejecutes la función hmac()
, cuenta las secciones de 20 bytes (incluido el resto) y usa la siguiente tabla de referencia:
Número de sección | Valor counter_bytes |
---|---|
0 | Ninguno |
1 ... 256 | 1 byte. El valor aumenta de 0 a 255 de forma secuencial. |
257 ... 512 | 2 bytes. El valor del primer byte es 0; el valor del segundo byte aumenta de 0 a 255 de forma secuencial. |
513 ... 768 | 3 bytes. El valor de los primeros dos bytes es 0, el valor del último byte aumenta de 0 a 255 de manera secuencial. |
No se espera que la longitud de BidRequest.encrypted_hyperlocal_set
supere un kilobyte, incluso si se tiene en cuenta el crecimiento. Sin embargo, counter_bytes
puede ser el tiempo necesario para admitir un indicador de orientación hiperlocal de longitud arbitraria.
Esquema de encriptación
El esquema de encriptación para la señal de orientación hiperlocal se basa en el mismo esquema utilizado para desencriptar confirmaciones de precio.
Serialización: la señal de orientación hiperlocal, que es una instancia del objeto HyperlocalSet, como se define en el proto, primero se serializa por medio de
SerializeAsString()
en un arreglo de bytes.Encriptación: Luego, el arreglo de bytes se encripta con un esquema de encriptación personalizado diseñado para minimizar la sobrecarga de tamaño y, a la vez, garantizar la seguridad adecuada. El esquema de encriptación usa un algoritmo de HMAC con clave para generar un pad secreto basado en
initialization_vector
, que es único para el evento de impresión.
Pseudocódigo de encriptación
byte_array = SerializeAsString(HyperlocalSet object) pad = hmac(encryption_key, initialization_vector || counter_bytes ) // for each 20-byte section of byte_array ciphertext = pad <xor> byte_array // for each 20-byte section of byte_array integrity_signature = hmac(integrity_key, byte_array || initialization_vector) // first 4 bytes final_message = initialization_vector || ciphertext || integrity_signature
Esquema de desencriptación
Tu código de desencriptación debe 1) desencriptar la señal de segmentación hiperlocal con la clave de encriptación y 2) verificar los bits de integridad con la clave de integridad. Las claves se le proporcionarán durante la configuración de la cuenta. No hay restricciones en la forma en la que estructuras tu implementación. En general, deberías poder tomar el código de muestra y adaptarlo según tus necesidades.
- Genera tu teclado:
HMAC(encryption_key, initialization_vector || counter_bytes)
- XOR: Toma este resultado y
<xor>
con el texto cifrado para revertir la encriptación. - Verificar: La firma de integridad pasa 4 bytes de
HMAC(integrity_key, byte_array || initialization_vector)
.
Pseudocódigo de desencriptación
(initialization_vector, ciphertext, integrity_signature) = final_message // split up according to length rules pad = hmac(encryption_key, initialization_vector || counter_bytes) // for each 20-byte section of ciphertext byte_array = ciphertext <xor> pad // for each 20-byte section of ciphertext confirmation_signature = hmac(integrity_key, byte_array || initialization_vector) success = (confirmation_signature == integrity_signature)
Código de muestra C++
Aquí se incluye una función clave de nuestro código de ejemplo de desencriptación completo.
bool DecryptByteArray( const string& ciphertext, const string& encryption_key, const string& integrity_key, string* cleartext) { // Step 1. find the length of initialization vector and clear text. const int cleartext_length = ciphertext.size() - kInitializationVectorSize - kSignatureSize; if (cleartext_length < 0) { // The length cannot be correct. return false; } string iv(ciphertext, 0, kInitializationVectorSize); // Step 2. recover clear text cleartext->resize(cleartext_length, '\0'); const char* ciphertext_begin = string_as_array(ciphertext) + iv.size(); const char* const ciphertext_end = ciphertext_begin + cleartext->size(); string::iterator cleartext_begin = cleartext->begin(); bool add_iv_counter_byte = true; while (ciphertext_begin < ciphertext_end) { uint32 pad_size = kHashOutputSize; uchar encryption_pad[kHashOutputSize]; if (!HMAC(EVP_sha1(), string_as_array(encryption_key), encryption_key.length(), (uchar*)string_as_array(iv), iv.size(), encryption_pad, &pad_size)) { printf("Error: encryption HMAC failed.\n"); return false; } for (int i = 0; i < kBlockSize && ciphertext_begin < ciphertext_end; ++i, ++cleartext_begin, ++ciphertext_begin) { *cleartext_begin = *ciphertext_begin ^ encryption_pad[i]; } if (!add_iv_counter_byte) { char& last_byte = *iv.rbegin(); ++last_byte; if (last_byte == '\0') { add_iv_counter_byte = true; } } if (add_iv_counter_byte) { add_iv_counter_byte = false; iv.push_back('\0'); } } }
Ejemplo de indicadores y claves hiperlocales
Para probar y verificar tu código, haz lo siguiente:
- Convierte una string que contenga 308 caracteres hexadecimales en un arreglo de 154 bytes. Por ejemplo, con la siguiente string:
E2014EA201246E6F6E636520736F7572636501414243C0ADF6B9B6AC17DA218FB50331EDB376701309CAAA01246E6F6E636520736F7572636501414243C09ED4ECF2DB7143A9341FDEFD125D96844E25C3C202466E6F6E636520736F7572636502414243517C16BAFADCFAB841DE3A8C617B2F20A1FB7F9EA3A3600256D68151C093C793B0116DB3D0B8BE9709304134EC9235A026844F276797
convertirlo en un array de 154 bytes de la siguiente manera:const char serialized_result[154] = { 0xE2, 0x01, 0x4E, ... };
- Llama al método
BidRequest.ParsePartialFromString()
para deserializar el arreglo de 154 bytes en un búfer de protocoloBidRequest
.BidRequest bid_req; bid_req.ParsePartialFromString(serialzed_result);
- Verifica que
BidRequest
tenga solo 3 campos:encrypted_hyperlocal_set
Declarado en el mensajeBidReqeust
.encrypted_advertising_id
Declarado en el mensajeBidReqeust.Mobile
.encrypted_hashed_idfa
Declarado en el mensajeBidReqeust.Mobile
.
Por ejemplo:
encrypted_hyperlocal_set:( { 100, 100 }, { 200, -300 }, { -400, 500 }, { -600, -700 },) encrypted_advertising_id: { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 } encrypted_hashed_idfa : { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xF1 }
- Usa los siguientes
encryption_key
yintegrity_key
para desencriptar los 3 campos y verificar que los desencriptes correctamente.encryption_key = {0x02, 0xEE, 0xa8, 0x3c, 0x6c, 0x12, 0x11, 0xe1, 0x0b, 0x9f, 0x88, 0x96, 0x6c, 0xee, 0xc3, 0x49, 0x08, 0xeb, 0x94, 0x6f, 0x7e, 0xd6, 0xe4, 0x41, 0xaf, 0x42, 0xb3, 0xc0, 0xf3, 0x21, 0x81, 0x40}; integrity_key = {0xbf, 0xFF, 0xec, 0x55, 0xc3, 0x01, 0x30, 0xc1, 0xd8, 0xcd, 0x18, 0x62, 0xed, 0x2a, 0x4c, 0xd2, 0xc7, 0x6a, 0xc3, 0x3b, 0xc0, 0xc4, 0xce, 0x8a, 0x3d, 0x3b, 0xbd, 0x3a, 0xd5, 0x68, 0x77, 0x92};
Detecta ataques de respuesta inactivos
Para detectar ataques de respuesta inactivos, recomendamos filtrar las respuestas con una marca de tiempo que difiere significativamente de la hora del sistema después de considerar las diferencias de zona horaria. Nuestros servidores están configurados en hora PST/PDT.
Para obtener detalles de implementación, consulta "Cómo detectar ataques de respuesta inactiva" en el artículo Desencriptar confirmaciones de precio.
Biblioteca Java
En lugar de implementar los algoritmos criptográficos para codificar y decodificar los indicadores de orientación hiperlocales, puedes usar DoubleClickCrypto.java. Para obtener más información, consulta Criptografía.