Yayıncılar mobil konum verilerini posta koduna göre daha ayrıntılı olan Authorized Buyers'a iletirse Authorized Buyers, şifrelenmiş yeni bir alanda alıcılara #&39;hyperlocal' coğrafi sınır bildirimi gönderir: BidRequest.encrypted_hyperlocal_set
.
Zaman çizelgesi
- Kullanıcı reklam destekli bir mobil uygulama yükler ve uygulamanın cihaz konumuna erişip üçüncü taraflarla paylaşmasına izin verir. Bu uygulama ayrıca Google Ads SDK'sı ile entegre olup bu cihaz konumunu Google'a gönderir.
- Google sunucuları, kullanıcının gizliliğini korumak gibi, cihaz konumunun etrafındaki bir coğrafi çiti temsil eden özel bir hiper yerel hedefleme sinyali oluşturur.
- Google sunucuları, her alıcıya özel güvenlik anahtarını kullanarak hiper yerel hedefleme sinyalini serileştirir ve şifreler. Teklif vereninizin WINNING_PRICE makrosunun şifresini çözmek için aynı anahtarı kullandığını unutmayın.
- Teklif vereniniz, yerel mesafe hedefleme sinyalinin şifresini çözer ve bu protokolü bir protokol arabelleğine dönüştürür. Ardından, teklif vereniniz sinyali ve teklifi buna göre analiz edebilir.
Bağımlılıklar
Openssl gibi SHA-1 HMAC'yi destekleyen bir şifreleme kitaplığına ihtiyacınız olacaktır.
Tanım
Proto'da, aşağıdaki gibi bir yerel mesafe hedefleme sinyali tanımlanır:
// 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;
Her bir yerel hedefleme sinyali, bir veya daha fazla poligon ve bir merkez noktası içerir. Her bir poligon için yerel çaplı hedefleme sinyali şunları içerir:
- Poligona ait her köşenin enlem ve boylamı sırayla oluşturulur ve yinelenen bir
corners
alanı olarak aktarılır. - İsteğe bağlı
center_point
alanında iletilen coğrafi sınır çitinin yaklaşık geometrik merkezi.
Hedefleme sinyalinin yapısı
BidRequest.encrypted_hyperlocal_set
içerisindeki şifrelenmiş yerel mesafe hedefleme sinyali 3 bölüm içerir:
initialization_vector
: 16 bayt.ciphertext
: 20 baytlık bölümlerden oluşan dizi.integrity_signature
: 4 bayt.
{initialization_vector (16 bytes)}{ciphertext (20-byte sections)}{integrity_signature (4 bytes)}
ciphertext
baytlık dizi, 20 baytlık birden fazla bölüme ayrılır. Bunun dışında, son bölümün 1 ila 20 bayt dahil olabilir. Orijinal byte_array
öğesinin her bölümü için 20 baytlık ciphertext
değeri şu şekilde oluşturulur:
<byte_array <xor> HMAC(encryption_key, initialization_vector || counter_bytes)>
||
birleştiriliyor.
Tanımlar
Değişken | Ayrıntılar |
---|---|
initialization_vector |
16 bayt - gösterime özel. |
encryption_key |
32 bayt - hesap kurulumu sırasında sağlanır. |
integrity_key |
32 bayt - hesap kurulumu sırasında sağlanır. |
byte_array |
20 baytlık bölümlerdeki serileştirilmiş HyperlocalSet nesnesi. |
counter_bytes |
Bölümün sıra numarasını gösteren bayt değeri. Aşağıya bakın. |
final_message |
BidRequest.encrypted_hyperlocal_set alanı üzerinden gönderilen bayt dizisi. |
Operatörler | Ayrıntılar |
---|---|
hmac(key, data) |
SHA-1 HMAC, key kullanılarak data şifreleniyor. |
a || b |
a dizesi, b dizesiyle birleştirildi. |
Sayaç_baytlarını hesapla
counter_bytes
, ciphertext
sütununun her 20 baytlık bölümünün sırasını belirtir. Son bölümün 1 ila 20 bayt dahil olabileceğini unutmayın. hmac()
işlevinizi çalıştırırken counter_bytes
öğesini doğru değerle doldurmak için 20 baytlık bölümleri (kalanlar dahil) sayın ve aşağıdaki referans tablosunu kullanın:
Bölüm numarası | counter_bytes değer |
---|---|
0 | Yok |
1 ... 256 | 1 bayt. Değer, sırasıyla 0 ile 255 arasında artar. |
257 ... 512 | 2 bayt. İlk baytın değeri 0'dır. İkinci baytın değeri de sırasıyla 0 ile 255 arasında artar. |
513 ... 768 | 3 bayt. İlk iki baytın değeri 0'dır. Son baytın değeri de sırayla 0 ile 255 arasında artar. |
Büyümenin daha da dikkate alınmasının BidRequest.encrypted_hyperlocal_set
uzunluğunun bir kilobaytı aşmasını beklemiyoruz. Bununla birlikte, counter_bytes
rastgele bir yerel hedefleme sinyalini desteklemek için gereken süre kadar uzun olabilir.
Şifreleme şeması
Yerel mesafe hedefleme sinyali için şifreleme şeması, fiyat onaylarının şifresini çözmek için kullanılan şemaya dayanır.
Serileme: Proto'da tanımlandığı gibi HyperlocalSet nesnesinin bir örneği olan hiper yerel hedefleme sinyali, ilk olarak
SerializeAsString()
aracılığıyla bir bayt dizisine serileştirilir.Şifreleme: Bayt dizisi, yeterli güvenlik sağlarken boyutun ek yükünü en aza indirmek için tasarlanmış özel bir şifreleme şeması kullanılarak şifrelenir. Şifreleme şeması,
initialization_vector
etkinliğini temel alan ve gösterim etkinliğine özgü bir gizli pad oluşturmak için anahtarlı bir HMAC algoritması kullanır.
Şifreleme sözde kodu
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
Şifre çözme düzeni
Şifre çözme kodunuz 1) şifreleme anahtarını kullanarak yerel mesafe hedefleme sinyalinin şifresini çözmelidir ve 2) bütünlük bitlerini bütünlük anahtarıyla doğrulamalıdır. Anahtarlar, hesap kurulumu sırasında size sağlanır. Uygulamanızı nasıl yapılandıracağınız konusunda herhangi bir kısıtlama yoktur. Çoğu durumda, örnek kodu alıp ihtiyaçlarınıza göre uyarlayabilmeniz gerekir.
- pad'inizi oluşturun:
HMAC(encryption_key, initialization_vector || counter_bytes)
- XOR: Bu sonucu alın ve şifrelemeyi tersine çevirmek için şifre metniyle
<xor>
ekleyin. - Doğrulama: Bütünlük imzası, 4 baytlık
HMAC(integrity_key, byte_array || initialization_vector)
değerini iletir
Şifre çözme sözde kodu
(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)
Örnek C++ kodu
Burada, eksiksiz şifre çözme örnek kodumuzdan temel bir işlev verilmiştir.
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'); } } }
Örnek yerel mesafe sinyali ve anahtarları
Kodunuzu test etmek ve doğrulamak için:
- 308 on altılık karakter içeren bir dizeyi 154 baytlık bir diziye dönüştürün. Örneğin, aşağıdaki dizeyi dikkate alın:
E2014EA201246E6F6E636520736F7572636501414243C0ADF6B9B6AC17DA218FB50331EDB376701309CAAA01246E6F6E636520736F7572636501414243C09ED4ECF2DB7143A9341FDEFD125D96844E25C3C202466E6F6E636520736F7572636502414243517C16BAFADCFAB841DE3A8C617B2F20A1FB7F9EA3A3600256D68151C093C793B0116DB3D0B8BE9709304134EC9235A026844F276797
kodu aşağıdaki gibi 154 baytlık bir diziye dönüştürün:const char serialized_result[154] = { 0xE2, 0x01, 0x4E, ... };
- 154 baytlık diziyi bir
BidRequest
protokol arabelleğine serileştirmek içinBidRequest.ParsePartialFromString()
yöntemini çağırın.BidRequest bid_req; bid_req.ParsePartialFromString(serialzed_result);
BidRequest
alanında yalnızca 3 alan olduğunu doğrulayın:encrypted_hyperlocal_set
BidReqeust
mesajında tanımlandı.encrypted_advertising_id
BidReqeust.Mobile
mesajında tanımlandı.encrypted_hashed_idfa
BidReqeust.Mobile
mesajında tanımlandı.
Örneğin:
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 }
- 3 alanın şifresini çözmek ve bunların şifresinin doğru şekilde çözüldüğünü doğrulamak için aşağıdaki
encryption_key
veintegrity_key
öğelerini kullanın.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};
Eski yanıt saldırılarını tespit etme
Eski yanıt saldırılarının algılanması için, saat dilimi farklarını hesaba kattıktan sonra, yanıtları sistem saatinden önemli ölçüde farklı bir zaman damgasıyla filtrelemenizi öneririz. Sunucularımız PST/PDT saatine ayarlandı.
Uygulama ayrıntıları için Fiyat Onaylarının Şifresini Çözme başlıklı makaledeki "Eski İletilerin Saldırılarını Tespit Etme" bölümüne göz atın.
Java kitaplığı
Yerel mesafe hedefleme sinyallerini kodlamak ve kodlarını çözmek için kriptografik algoritmaları uygulamak yerine DoubleClickCrypto.java'yı kullanabilirsiniz. Daha fazla bilgi için Kriptografi bölümüne bakın.