Se i publisher trasmettono ad Authorized Buyers dati sulla posizione su dispositivi mobili più specifici di un codice postale, Authorized Buyers invierà un'area di recinzione"hyperlocal'"agli acquirenti in un nuovo campo criptato: BidRequest.encrypted_hyperlocal_set
.
Sequenza temporale
- Un utente installa un'app per dispositivi mobili con pubblicità e autorizza l'app ad accedere e a condividere la posizione del dispositivo con terze parti. Questa app è integrata con l'SDK Google Ads e invia la posizione di questo dispositivo a Google.
- I server di Google generano uno speciale segnale di targeting iperlocale che rappresenta un recinto virtuale che circonda la posizione del dispositivo, ad esempio per proteggere la privacy dell'utente.
- I server Google serializzano e criptano l'indicatore di targeting iperlocale utilizzando il token di sicurezza specifico di ciascun acquirente. Tieni presente che lo strumento di offerta si basa sulla stessa chiave per decriptare la macro WINNING_PRICE.
- Lo strumento di offerta decripta e deserializza l'indicatore di targeting iperlocale in un buffer di protocollo. Lo strumento di offerta può quindi analizzare l'indicatore e fare offerte di conseguenza.
Dipendenze
Avrai bisogno di una libreria di crittografia che supporti SHA-1 HMAC, ad esempio Openssl.
Definizione
Un protocollo di targeting iperlocale è definito nel protocollo in questo modo:
// 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;
Ogni indicatore di targeting iperlocale contiene uno o più poligoni e un punto centrale. Per ogni poligono, l'indicatore di targeting iperlocale contiene:
- La latitudine e la longitudine di ogni angolo del poligono, passate come un campo
corners
ripetuto. - Il centro geometrico approssimativo dell'area del recinto virtuale, passato nel campo facoltativo
center_point
.
Struttura dell'indicatore di targeting
L'indicatore di targeting iperlocale criptato contenuto in BidRequest.encrypted_hyperlocal_set
contiene 3 sezioni:
initialization_vector
: 16 byte.ciphertext
: serie di sezioni da 20 byte.integrity_signature
: 4 byte.
{initialization_vector (16 bytes)}{ciphertext (20-byte sections)}{integrity_signature (4 bytes)}
L'array di ciphertext
byte è diviso in più sezioni da 20 byte, ad eccezione del fatto che l'ultima sezione può contenere da 1 a 20 byte inclusi. Per ogni sezione dell'originale
byte_array
, il corrispondente ciphertext
di 20 byte viene
generato come:
<byte_array <xor> HMAC(encryption_key, initialization_vector || counter_bytes)>
Dove ||
è concatenata.
Definizioni
Variabile | Dettagli |
---|---|
initialization_vector |
16 byte: univoco per l'impressione. |
encryption_key |
32 byte: fornito durante la creazione dell'account. |
integrity_key |
32 byte: fornito durante la creazione dell'account. |
byte_array |
Un oggetto HyperlocalSet serializzato, in sezioni da 20 byte. |
counter_bytes |
Il valore in byte mostra il numero ordinale della sezione, vedi di seguito. |
final_message |
Array di byte inviati tramite il campo BidRequest.encrypted_hyperlocal_set . |
Operatori | Dettagli |
---|---|
hmac(key, data) |
MAC H-SHA-1, utilizzando key per criptare data . |
a || b |
stringa a concatenata con stringa b . |
Calcolare contatori_byte
counter_bytes
contrassegna l'ordine di ogni sezione di 20 byte del
ciphertext
. Tieni presente che l'ultima sezione può contenere da 1 a 20 byte inclusi. Per riempire counter_bytes
con il valore corretto
quando esegui la funzione hmac()
, conteggia le sezioni di 20 byte
(incluso il resto) e utilizza la seguente tabella di riferimento:
Numero sezione | Valore counter_bytes |
---|---|
0 | Nessuno |
1...256 | 1 byte. Il valore aumenta da 0 a 255 in sequenza. |
257...512 | 2 byte. Il valore del primo byte è 0, il valore del secondo byte aumenta da 0 a 255 in sequenza. |
513... 768 | 3 byte. Il valore dei primi due byte è 0, il valore dell'ultimo byte aumenta da 0 a 255 in sequenza. |
Non prevediamo che la lunghezza di BidRequest.encrypted_hyperlocal_set
superi il limite di 1 kilobyte, anche in considerazione di un'ulteriore crescita. Tuttavia, il valore counter_bytes
può essere sufficiente per supportare un indicatore di targeting iperlocale di durata arbitraria.
Schema di crittografia
Lo schema di crittografia per l'indicatore di targeting iperlocale si basa sullo stesso schema utilizzato per la decriptazione delle conferme di prezzo.
Serializzazione: l'indicatore di targeting iperlocale, che è un'istanza dell'oggetto HyperlocalSet come definito nel proto, viene prima serializzato tramite
SerializeAsString()
in un array di byte.Crittografia: l'array di byte viene quindi criptato utilizzando uno schema di crittografia personalizzato progettato per ridurre al minimo l'overhead di dimensione e garantire comunque una sicurezza adeguata. Lo schema di crittografia utilizza un algoritmo HMAC con chiave per generare un pad segreto in base al
initialization_vector
, che è univoco per l'evento di impressione.
Pseudo codice di crittografia
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
Schema di decriptazione
Il codice di decriptazione deve 1) decriptare il segnale di targeting iperlocale utilizzando la chiave di crittografia e 2) verificare i bit di integrità con la chiave di integrità. Le chiavi ti verranno fornite durante la creazione dell'account. Non ci sono limitazioni alla strutturazione della tua implementazione. Nella maggior parte dei casi, dovresti essere in grado di prendere il codice di esempio e adattarlo in base alle tue esigenze.
- Genera il pad:
HMAC(encryption_key, initialization_vector || counter_bytes)
- XOR: utilizza questo risultato e
<xor>
con il testo criptato per invertire la crittografia. - Verifica: la firma di integrità trasmette 4 byte di
HMAC(integrity_key, byte_array || initialization_vector)
Pseudocodice di decriptazione
(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)
Codice C++ di esempio
Questa è una funzione chiave del nostro codice di esempio di decriptazione 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'); } } }
Esempio di segnali e chiavi iperlocali
Per verificare e verificare il codice:
- Converti una stringa contenente 308 caratteri esadecimali in un array di 154 byte. Ad esempio, data la seguente stringa:
E2014EA201246E6F6E636520736F7572636501414243C0ADF6B9B6AC17DA218FB50331EDB376701309CAAA01246E6F6E636520736F7572636501414243C09ED4ECF2DB7143A9341FDEFD125D96844E25C3C202466E6F6E636520736F7572636502414243517C16BAFADCFAB841DE3A8C617B2F20A1FB7F9EA3A3600256D68151C093C793B0116DB3D0B8BE9709304134EC9235A026844F276797
convertirlo in un array di 154 byte nel seguente modo:const char serialized_result[154] = { 0xE2, 0x01, 0x4E, ... };
- Richiama il metodo
BidRequest.ParsePartialFromString()
per deserializzare l'array da 154 byte in un buffer di protocolloBidRequest
.BidRequest bid_req; bid_req.ParsePartialFromString(serialzed_result);
- Verifica che
BidRequest
abbia solo 3 campi:encrypted_hyperlocal_set
Dichiarati nel messaggioBidReqeust
.encrypted_advertising_id
Dichiarati nel messaggioBidReqeust.Mobile
.encrypted_hashed_idfa
Dichiarati nel messaggioBidReqeust.Mobile
.
Ad esempio:
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 }
- Utilizza i seguenti
encryption_key
eintegrity_key
per decriptare i tre campi e verificare che vengano decriptati correttamente.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};
Rileva gli attacchi di risposta inattiva
Per rilevare gli attacchi di risposta inattiva, ti consigliamo di filtrare le risposte con un timestamp che differisce in modo significativo dall'ora di sistema, dopo aver preso in considerazione le differenze di fuso orario. I nostri server sono impostati sul fuso orario PST/PDT.
Per maggiori dettagli sull'implementazione, leggi la sezione "Rilevamento di attacchi di risposta inattive" nell'articolo Decriptare le conferme di prezzo.
Libreria Java
Invece di implementare gli algoritmi di crittografia per codificare e decodificare gli indicatori di targeting iperlocale, puoi utilizzare DoubleClickCrypto.java. Per ulteriori informazioni, consulta la pagina Crittografia.