Reklam öğeniz bir açık artırmayı kazandığında Google, reklam öğesi ${AUCTION_PRICE}
makrosunu içeriyorsa kazanan fiyatı size bildirebilir.
Makro genişletildiğinde, kazanan fiyatı şifrelenmiş biçimde döndürür. Örneğin, reklamın bir parçası olarak oluşturulan görünmez bir piksel isteğiyle reklam öğesine dahil edilebilir:
<div> <script language='JavaScript1.1' src='https://example.com?creativeID=5837243'/> <img src='https://example.com/t.gif?price=${AUCTION_PRICE}' width='1' height='1'/> </div>
${AUCTION_PRICE}
makrosu, bir video reklam öğesinin VAST URL'sine de dahil edilebilir ancak VAST'teki gösterim URL'sine dahil edilemez:
https://example.com/vast/v?price=${AUCTION_PRICE}
Senaryo
- OpenRTB teklifli sistem uygulamanız, Google'a döndürdüğü HTML snippet'inde veya VAST URL'sinde
${AUCTION_PRICE}
makrosunu içeriyor. - Google, kazanan fiyatı makronun yerine doldurulmamış web güvenli base64 kodlamasıyla (RFC 3548) yerleştirir.
- Sana Özel snippet'i, seçtiğiniz biçimde onay alır. Örneğin, onay, reklamın bir parçası olarak oluşturulan görünmez bir piksel isteğinin URL'sinde iletilebilir.
- Sunucudaki uygulamanız, web'de güvenli base64 kullanarak kazanan fiyat bilgilerinin ve sonucun şifresini çözer.
Bağımlılıklar
Openssl gibi SHA-1 HMAC'yi destekleyen bir şifreleme kitaplığınız olmalıdır.
Örnek kod
Java ve C++'da sağlanan örnek kodu privatedatacommunicationprotocol projesinden indirebilirsiniz.
Java örnek kodu, Apache Commons projesindeki base64 kod çözücüyü kullanır. Referans uygulama gerekli kısmı içerdiğinden ve bu nedenle kendi kendine yeterli olduğundan Apache commons kodunu indirmeniz gerekmez.
C++ örnek kodunda OpenSSL base64 BIO yöntemi kullanılmaktadır. Web için güvenli base64 kodlu bir dize (RFC 3548) alır ve bu dizenin kodunu çözer. Normalde web'de güvenli base64 dizeleri, "=" dolgusunu "." ile değiştirir (tırnak işaretlerinin okunabilirliği artırmak için eklendiğini ve protokole dahil edilmediğini unutmayın). Ancak makro değiştirme, şifrelenmiş fiyatı doldurmaz. OpenSSL, doldurulmamış dizelerle ilgili sorun yaşadığından referans uygulamada doldurma işlemi eklenir.
Kodlama
Kazanan fiyat şifreleme ve şifre çözme işlemi için iki gizli ancak paylaşılan anahtar gerekir. Sırasıyla i_key
ve e_key
olarak adlandırılan bir bütünlük anahtarı ve şifreleme anahtarı. Her iki anahtar da hesap kurulumunda web'de güvenli base64 dizesi olarak sağlanır ve Authorized Buyers sayfasındaki Teklif veren ayarları > GZT ayarları > Şifreleme anahtarları bölümünde bulunabilir.
Örnek bütünlük ve şifreleme anahtarları:
skU7Ax_NL5pPAFyKdkfZjZz2-VhIN8bjj1rVFOaJ_5o= // Encryption key (e_key) arO23ykdNqUQ5LEoQ0FVmPkBd7xB5CO89PDZlSjpFxo= // Integrity key (i_key)
Anahtarlar, uygulamanız tarafından web için güvenli şekilde kod çözülmeli ve ardından base64 olarak kod çözülmelidir:
e_key = WebSafeBase64Decode('skU7Ax_NL5pPAFyKdkfZjZz2-VhIN8bjj1rVFOaJ_5o=') i_key = WebSafeBase64Decode('arO23ykdNqUQ5LEoQ0FVmPkBd7xB5CO89PDZlSjpFxo=')
Şifreleme şeması
Fiyat, yeterli güvenlik sağlarken boyut yükü en aza indirmek için tasarlanmış özel bir şifreleme şeması kullanılarak şifrelenir. Şifreleme şeması, benzersiz gösterim etkinliği kimliğine göre gizli bir blok oluşturmak için anahtarlanmış bir HMAC algoritması kullanır.
Şifrelenmiş fiyat 28 bayt uzunluğundadır. 16 baytlık bir başlatma vektörü, 8 bayt şifrelenmiş metin ve 4 baytlık bir bütünlük imzasından oluşur. Şifrelenmiş fiyat, RFC 3548'e göre web güvenli base64 kodlu ve dolgu karakterleri atlanmış şekildedir. Bu nedenle, 28 baytlık şifrelenmiş fiyat, ödenen kazanan fiyattan bağımsız olarak 38 karakterli web'de güvenli base64 dizesi olarak kodlanır.
Şifrelenmiş fiyatlar örneği:
YWJjMTIzZGVmNDU2Z2hpN7fhCuPemCce_6msaw // 100 CPI micros YWJjMTIzZGVmNDU2Z2hpN7fhCuPemCAWJRxOgA // 1900 CPI micros YWJjMTIzZGVmNDU2Z2hpN7fhCuPemC32prpWWw // 2700 CPI micros
Şifrelenmiş biçim:
{initialization_vector (16 bytes)}{encrypted_price (8 bytes)} {integrity (4 bytes)}
Fiyat <price xor HMAC(encryption_key,
initialization_vector)>
olarak şifrelenir. Bu nedenle şifre çözme işlemi, şifrelemeyi tersine çevirmek için HMAC(encryption_key,initialization_vector)
değerini hesaplar ve şifrelenmiş fiyatla xor işlemi yapar. Bütünlük aşaması, ||
birleştirme işlemi olduğunda 4 bayt <HMAC(integrity_key, price||initialization_vector)>
alır.
Girişler | |
---|---|
iv |
başlatma vektörü (16 bayt - gösterime özgüdür) |
e_key |
şifreleme anahtarı (32 bayt - hesap kurulumunda sağlanır) |
i_key |
bütünlük anahtarı (32 bayt - hesap kurulumunda sağlanır) |
price |
(8 bayt - hesap para biriminin mikro cinsinden değeri) |
Nota | |
hmac(k, d) |
k anahtarını kullanarak d verilerinin SHA-1 HMAC'si |
a || b |
a dizesi, b dizesiyle birleştirilmiştir |
Sözde kod | |
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 ) |
Şifre çözme şeması
Şifre çözme kodunuz, şifreleme anahtarını kullanarak fiyatın şifresini çözmeli ve bütünlük bitlerini bütünlük anahtarıyla doğrulamalıdır. Anahtarlar kurulum sırasında size sağlanır. Uygulamanızı nasıl yapılandıracağınızla ilgili ayrıntılar konusunda herhangi bir kısıtlama yoktur. Çoğu durumda, örnek kodu alıp ihtiyaçlarınıza göre uyarlayabilirsiniz.
Girişler | |
---|---|
e_key |
şifreleme anahtarı, 32 bayt - hesap kurulumunda sağlanır |
i_key |
Bütünlük anahtarı, 32 bayt - hesap kurulumunda sağlanır |
final_message |
38 karakter, web güvenli base64 kodlu |
Sözde kod | |
// Base64 padding characters are omitted. // Add any required base64 padding (= or ==). final_message_valid_base64 = AddBase64Padding(final_message) // Web-safe decode, then base64 decode. enc_price = WebSafeBase64Decode(final_message_valid_base64) // Message is decoded but remains encrypted. (iv, p, sig) = enc_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) |
Eski yanıt saldırılarını algılama
Eski yanıt veya yeniden oynatma saldırılarını tespit etmek için saat dilimi farklılıklarını hesaba katarak yanıtları, sistem zamanından önemli ölçüde farklı bir zaman damgasına sahip olanlarla filtrelemeniz önerilir.
İlk 8 bayt, başlatma vektöründe bir zaman damgası içerir. Aşağıdaki C++ işlevi tarafından okunabilir:
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) }
Zaman damgası, aşağıdaki C++ kodu kullanılarak kullanıcı tarafından okunabilir bir forma dönüştürülebilir:
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);
Java kitaplığı
Kazanan fiyatı kodlamak ve kodunu çözmek için kriptografik algoritmaları uygulamak yerine DoubleClickCrypto.java dosyasını kullanabilirsiniz. Daha fazla bilgi için Kriptografi bölümüne bakın.