Reklam öğeniz bir açık artırmayı kazandığında, reklam öğesini tanımlayan HTML snippet'i veya VAST URL'si WINNING_PRICE
makrosunu içeriyorsa Google, kazanan fiyatın ne olduğunu size bildirebilir. Google, kazanan fiyatı şifrelenmiş biçimde döndürür. Aşağıdaki konularda, uygulamanızın kazanan fiyat bilgilerinin şifresini nasıl çözebileceği açıklanmaktadır.
WINNING_PRICE
makrosu bir reklam öğesine eklenebilir. Örneğin, reklamın parçası olarak görünmez bir piksel isteği oluşturulabilir:
<div> <script language='JavaScript1.1' src='https://example.com?creativeID=5837243'/> <img src='https://example.com/t.gif?price=%%WINNING_PRICE%%' width='1' height='1'/> </div>
WINNING_PRICE
makrosu, bir video reklam öğesinin VAST URL'sine de dahil edilebilir (ancak VAST'taki gösterim URL'sine dahil edilemez):
https://example.com/vast/v?price=%%WINNING_PRICE%%
Senaryo
- Uygulamanız,
WINNING_PRICE
makrosunu HTML snippet'inde veya Google'a döndürdüğü VAST URL'sinde içeriyor. - Google, makronun kazanan fiyatını doldurulmamış web için güvenli base64 kodlamasıyla (RFC 3548) değiştirir.
- Snippet, onayı seçtiğiniz biçimde iletir. Örneğin, onay, reklamın parçası olarak oluşturulan görünmez bir piksel isteğinin URL'sinde iletilebilir.
- Sunucuda, web güvenli base64 uygulamanız kazanan fiyat bilgilerinin kodunu çözer ve sonucun şifresini çözer.
Bağımlılıklar
SHA-1 HMAC'yi destekleyen Openssl gibi bir şifreleme kitaplığına ihtiyacınız olacaktır.
Örnek kod
Örnek kod, Java ve C++'ta sağlanır ve privatedatacommunicationprotocol projesinden indirilebilir.
Java örnek kodu, Apache Commons projesindeki base64 kod çözücüyü kullanır. Referans uygulaması gerekli bölümü içerdiğinden ve bu nedenle bağımsız olduğundan Apache Commons kodunu indirmeniz gerekmez.
C++ örnek kodu, OpenSSL base64 BIO yöntemini kullanır. Web güvenli base64 kodlu bir dize (RFC 3548) alır ve kodunu çözer. Normalde web güvenli base64 dizeleri, "=" dolgusunu "." ile değiştirir (okumanın daha kolay anlaşılması için tırnak işaretleri eklendiğini ve protokole dahil edilmediğini unutmayın) ancak makro değişikliği, şifrelenmiş fiyatı doldurmaz. Referans uygulaması, OpenSSL doldurulmamış dizelerle ilgili sorun yaşadığından dolgu ekler.
Kodlama
Fiyat şifreleme ve şifre çözmeyi kazanmak 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 kurulumu sırasında web için güvenli base64 dizeleri olarak sağlanır ve Authorized Buyers sayfasında Teklif veren ayarları > RTB ayarları > Şifreleme anahtarları altında bulunabilir.
Örnek bütünlük ve şifreleme anahtarları:
skU7Ax_NL5pPAFyKdkfZjZz2-VhIN8bjj1rVFOaJ_5o= // Encryption key (e_key) arO23ykdNqUQ5LEoQ0FVmPkBd7xB5CO89PDZlSjpFxo= // Integrity key (i_key)
Anahtarların kodu web'de şifrelenmeli ve uygulamanız tarafından base64 kodu çözilmelidir:
e_key = WebSafeBase64Decode('skU7Ax_NL5pPAFyKdkfZjZz2-VhIN8bjj1rVFOaJ_5o=') i_key = WebSafeBase64Decode('arO23ykdNqUQ5LEoQ0FVmPkBd7xB5CO89PDZlSjpFxo=')
Şifreleme şeması
Fiyat, yeterli güvenlik sağlarken boyut ek yükünü en aza indirmek için tasarlanmış özel bir şifreleme şeması kullanılarak şifrelenir. Şifreleme şeması, benzersiz gösterim etkinlik kimliğine dayalı bir gizli alan oluşturmak için anahtarlı bir HMAC algoritması kullanır.
Şifrelenmiş fiyatın 28 bayt sabit uzunluğu vardır. 16 baytlık bir başlatma vektörü, 8 baytlık şifrelenmiş metin ve 4 baytlık bütünlük imzasından oluşur. Şifrelenmiş fiyat, RFC 3548'e göre web için güvenli base64 kodludur ve dolgu karakterleri atlanır. Bu nedenle 28 bayt şifreli fiyat, ödenen fiyattan bağımsız olarak 38 karakterli web için güvenli base 64 dizesi olarak kodlanır.
Şifrelenmiş fiyatlara örnek:
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 şifrelendiğinden şifre çözme işlemi, şifrelemeyi tersine çevirmek için şifrelenmiş fiyatı HMAC(encryption_key,initialization_vector)
ve xor'u hesaplar. Bütünlük aşaması, <HMAC(integrity_key, price||initialization_vector)>
boyutunda 4 baytlık alanı kaplar. Burada ||
, birleştirme işlemidir.
Girişler | |
---|---|
iv |
başlatma vektörü (16 bayt - gösterime özel) |
e_key |
şifreleme anahtarı (32 bayt, hesap kurulumu sırasında sağlanır) |
i_key |
bütünlük anahtarı (32 bayt, hesap kurulumu sırasında sağlanır) |
price |
(8 bayt: hesap para biriminin mikro cinsinden ifadesi) |
Notasyon | |
hmac(k, d) |
d verilerinin SHA-1 HMAC'si (k anahtarı kullanılarak) |
a || b |
a dizesi b dizesiyle birleştirildi |
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 verilir. Uygulamanızı nasıl yapılandıracağınızla ilgili ayrıntılara dair herhangi bir kısıtlama yoktur. Çoğunlukla, örnek kodu alıp ihtiyaçlarınıza göre uyarlamanız gerekir.
Girişler | |
---|---|
e_key |
şifreleme anahtarı, 32 bayt (hesap kurulumu sırasında sağlanır) |
i_key |
bütünlük anahtarı, 32 bayt (hesap kurulumu sırasında sağlanır) |
final_message |
38 karakter uzunluğunda 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ı tespit etme
Eski yanıtları veya tekrar saldırıları tespit etmek için, saat dilimi farklarını hesaba kattıktan sonra, sistem saatinden önemli ölçüde farklı bir zaman damgasına sahip yanıtları filtrelemeniz önerilir.
Başlatma vektörü, ilk 8 baytta bir zaman damgası içerir. Aşağıdaki C++ işleviyle 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 insanların okuyabileceği 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 kripto algoritmalarını uygulamak yerine DoubleClickCrypto.java'yı kullanabilirsiniz. Daha fazla bilgi için Kriptografi konusuna bakın.