Odszyfrowywanie potwierdzeń cen

Gdy Twoja kreacja wygra aukcję, Google może podać Ci informacje cena była tylko wtedy, gdy kreacja zawiera odpowiednie makro.

Jeśli licytujący został skonfigurowany pod kątem korzystania z protokołu OpenRTB, kreacja uwzględnione w stawce powinny korzystać z zasad ${AUCTION_PRICE} IAB. .

Jeśli licytujący używa wycofanego protokołu RTB Google, kreacja powinna skorzystaj z narzędzia %%WINNING_PRICE%% Google .

Po rozwinięciu tych makr zwracają najlepszą cenę w zaszyfrowanego formularza. Można je umieścić w kreacji, np. za pomocą tagu niewidoczne żądanie piksela renderowane jako część reklamy:

<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>

Makro ${AUCTION_PRICE} można również umieścić w adresie URL VAST tagu kreacji wideo, ale nie w adresie URL wyświetlenia w tagu VAST:

https://example.com/vast/v?price=${AUCTION_PRICE}

Scenariusz

  1. Twoja aplikacja do określania stawek OpenRTB zawiera te składniki: ${AUCTION_PRICE} we fragmencie kodu HTML lub adresie URL VAST zwracanym do Google.
  2. Google zastępuje zwycięską cenę makro w niedopełnionym środowisku, które jest bezpieczne w internecie kodowanie base64 (RFC 3548).
  3. Fragment kodu przechodzi weryfikację w wybranym przez Ciebie formacie. Dla: potwierdzenie może być przekazywane w adresie URL niewidocznego piksela żądania renderowane jako część reklamy.
  4. Na serwerze Twoja aplikacja, która można używać w przeglądarce, dekoduje zwycięską cenę i odszyfrowuje wynik.

Zależności

Potrzebujesz biblioteki kryptograficznej obsługującej SHA-1 HMAC, takiej jak Openssl.

Przykładowy kod

Przykładowy kod jest dostępny w Javie i C++ i można go pobrać z privatedatacommunicationprotocol projekt.

  • Przykładowy kod w Javie korzysta z dekodera base64 z serwera Apache z projektem Commons. Nie musisz pobierać kodu Apache Commons ponieważ implementacja referencyjna obejmuje niezbędną część, dlatego jest niezależne od siebie.

  • Przykładowy kod w C++ korzysta z protokołu OpenSSL base64 BIO. Pobiera i dekoduje odpowiedni w internecie ciąg zakodowany w standardzie base64 (RFC 3548). Zwykle bezpieczne w internecie ciągi base64 zastępują „=”. dopełnienie z „.” (zwróć uwagę, że cudzysłowy zostały dodane w celu zapewnienia czytelności i nie są uwzględnione w protokołu), ale zastąpienie makr nie wypełnia zaszyfrowanej ceny. implementacja odwołania dodaje dopełnienie, ponieważ OpenSSL ma problemy z ciągi bez dopełnienia.

Kodowanie

Zwycięskie szyfrowanie i odszyfrowanie ceny wymaga 2 obiektów tajnych, ale udostępnionych klawiszy. klucz integralności i klucz szyfrowania (i_key). i e_key. Oba klucze są przekazywane podczas zakładania konta jako bezpieczne w internecie ciągi tekstowe w formacie base64, które można znaleźć na stronie Authorized Buyers. w sekcji Licytujący Ustawienia > Ustawienia RTB > Klucze szyfrowania

Przykładowe klucze integralności i szyfrowania:

skU7Ax_NL5pPAFyKdkfZjZz2-VhIN8bjj1rVFOaJ_5o=  // Encryption key (e_key)
arO23ykdNqUQ5LEoQ0FVmPkBd7xB5CO89PDZlSjpFxo=  // Integrity key (i_key)

Klucze powinny być zdekodowane w internecie, a następnie zdekodowane za pomocą base64 aplikacja:

e_key = WebSafeBase64Decode('skU7Ax_NL5pPAFyKdkfZjZz2-VhIN8bjj1rVFOaJ_5o=')
i_key = WebSafeBase64Decode('arO23ykdNqUQ5LEoQ0FVmPkBd7xB5CO89PDZlSjpFxo=')

Schemat szyfrowania

Cena jest szyfrowana przy użyciu niestandardowego schematu szyfrowania, które ma zminimalizują duże nakłady pracy przy jednoczesnym zapewnieniu odpowiedniego bezpieczeństwa. Schemat szyfrowania wykorzystuje algorytm HMAC z kluczem do wygenerowania tajnej paczki na podstawie unikalnego kodu identyfikator zdarzenia wyświetlenia.

Zaszyfrowana cena ma stałą długość 28 bajtów. Składa się on z 16-bajtowy wektor inicjujący, 8 bajtów tekstu zaszyfrowanego i 4-bajtowa integralność podpis. Zgodnie z RFC zaszyfrowana cena jest w bezpieczny sposób zakodowana w formacie base64 3548 z pominiętymi znakami dopełnienia. Zaszyfrowana cena z 28 bajtami zakodowane jako 38-znakowy, bezpieczny dla sieci ciąg base-64, niezależnie od zwycięskiego ciągu zapłaconą cenę.

Przykładowe zaszyfrowane ceny:

YWJjMTIzZGVmNDU2Z2hpN7fhCuPemCce_6msaw  // 100 CPI micros
YWJjMTIzZGVmNDU2Z2hpN7fhCuPemCAWJRxOgA  // 1900 CPI micros
YWJjMTIzZGVmNDU2Z2hpN7fhCuPemC32prpWWw  // 2700 CPI micros

Format zaszyfrowany to:

{initialization_vector (16 bytes)}{encrypted_price (8 bytes)}
{integrity (4 bytes)}

Cena jest zaszyfrowana jako <price xor HMAC(encryption_key, initialization_vector)>, więc odszyfrowanie oblicza wynik HMAC(encryption_key,initialization_vector) i xor z zaszyfrowaną cenę w celu odwrócenia szyfrowania. Etap integralności zajmuje 4 bajty <HMAC(integrity_key, price||initialization_vector)>, gdzie || to konkatenacja.

Dane wejściowe
iv wektor inicjujący (16 bajtów – unikalny dla wyświetlenia)
e_key klucz szyfrowania (32 bajty – podawany podczas konfigurowania konta)
i_key klucz integralności (32 bajty – podawany podczas konfigurowania konta).
price (8 bajtów – w mikro waluty konta)
Zapis
hmac(k, d) Kod HMAC SHA-1 danych d, przy użyciu klucza k
a || b ciąg znaków a połączony z ciągiem b
Pseudokod
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 )

Schemat odszyfrowywania

Twój kod odszyfrowywania musi odszyfrować cenę za pomocą klucza szyfrowania. zweryfikować bity za pomocą klucza integralności. Klucze zostaną przekazane podczas konfiguracji. Nie ma żadnych ograniczeń dotyczących sposobu, strukturę implementacji. Musisz być w stanie zrobić przykładowy kod i dostosuj go do swoich potrzeb.

Dane wejściowe
e_key klucz szyfrowania 32 bajty – udostępniany podczas zakładania konta
i_key klucz integralności 32 bajty (podawany podczas konfiguracji konta)
final_message 38 znaków, w formacie base64 dostępnym w sieci
Pseudokod
// 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)

Wykrywanie nieaktualnych ataków odpowiedzi

W celu wykrywania nieaktualnych odpowiedzi (ponownych odtworzeń ataków) zalecamy wykonanie tych czynności filtrowanie odpowiedzi o sygnaturze czasowej znacznie różniącym się od systemu po uwzględnieniu różnic stref czasowych.

Wektor inicjujący zawiera sygnaturę czasową w pierwszych 8 bajtach. Może może zostać odczytana przez tę funkcję w C++:

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)
}

Sygnaturę czasową można przekonwertować do postaci czytelnej dla człowieka za pomocą: Kod w C++:

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);

Biblioteka Java

Zamiast implementować algorytmy kryptograficzne do kodowania i dekodowania zwycięską cenę, możesz użyć DoubleClickCrypto.java. Więcej informacji: Kryptografia.