رمزگشایی تأییدیه های قیمت

وقتی خلاقیت شما در حراجی برنده می‌شود، اگر قطعه HTML یا URL VAST که خلاقیت را تعریف می‌کند شامل ماکرو WINNING_PRICE باشد، Google می‌تواند به شما اطلاع دهد که قیمت برنده چقدر بوده است. گوگل قیمت برنده را به صورت رمزگذاری شده برمی گرداند. موضوعات زیر توضیح می دهند که چگونه برنامه شما می تواند اطلاعات قیمت برنده را رمزگشایی کند.

ماکرو WINNING_PRICE را می‌توان در یک خلاقیت گنجاند، برای مثال، با یک درخواست پیکسل نامرئی که به عنوان بخشی از آگهی ارائه می‌شود:

<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 همچنین می‌تواند در URL VAST یک ویدیوی خلاقانه گنجانده شود (اما نه در نشانی اینترنتی نمایش در VAST):

https://example.com/vast/v?price=%%WINNING_PRICE%%

سناریو

  1. برنامه شما شامل ماکرو WINNING_PRICE در قطعه HTML یا URL VAST است که به Google برمی‌گرداند.
  2. Google قیمت برنده را برای ماکرو در رمزگذاری پایه 64 ایمن وب بدون پد ( RFC 3548 ) جایگزین می‌کند.
  3. قطعه تأیید را در قالبی که شما انتخاب کرده اید ارسال می کند. برای مثال، تأیید ممکن است در URL درخواست پیکسل نامرئی که به عنوان بخشی از آگهی ارائه شده است، ارسال شود.
  4. در سرور، برنامه web-safe base64 شما اطلاعات قیمت برنده را رمزگشایی می کند و نتیجه را رمزگشایی می کند.

وابستگی ها

شما به یک کتابخانه رمزنگاری نیاز دارید که از SHA-1 HMAC پشتیبانی کند، مانند Openssl.

کد نمونه

کد نمونه به زبان جاوا و C++ ارائه شده است و از پروژه privatedatacommunicationprotocol قابل دانلود است.

  • کد نمونه جاوا از رمزگشای base64 از پروژه مشترک Apache استفاده می کند. نیازی به دانلود کد مشترک آپاچی نخواهید داشت، زیرا پیاده سازی مرجع شامل بخش ضروری است و بنابراین مستقل است.

  • کد نمونه C++ از روش OpenSSL base64 BIO استفاده می کند. یک رشته رمزگذاری شده مبتنی بر وب ایمن base64 ( RFC 3548 ) را می گیرد و آن را رمزگشایی می کند. به طور معمول، رشته‌های web-safe base64 جایگزین "=" padding با "." (توجه داشته باشید که علامت نقل قول برای وضوح خواندن اضافه شده است و در پروتکل گنجانده نشده است) اما جایگزینی ماکرو قیمت رمزگذاری شده را کاهش نمی دهد. پیاده سازی مرجع padding را اضافه می کند زیرا OpenSSL با رشته های بدون پد مشکل دارد.

رمزگذاری

رمزگذاری و رمزگشایی قیمت برنده نیاز به دو کلید مخفی اما مشترک دارد. یک کلید یکپارچگی و کلید رمزگذاری که به ترتیب i_key و e_key نامیده می‌شوند. هر دو کلید در راه‌اندازی حساب به‌عنوان رشته‌های base64 امن برای وب ارائه می‌شوند و می‌توانید آن را در صفحه خریداران مجاز در قسمت تنظیمات پیشنهاد دهنده > تنظیمات RTB > کلیدهای رمزگذاری پیدا کنید.

نمونه کلیدهای یکپارچگی و رمزگذاری:

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

کلیدها باید به صورت ایمن وب رمزگشایی شوند و سپس توسط برنامه شما از طریق base64 رمزگشایی شوند:

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

طرح رمزگذاری

قیمت با استفاده از یک طرح رمزگذاری سفارشی رمزگذاری شده است که برای به حداقل رساندن حجم سربار طراحی شده است و در عین حال امنیت کافی را تضمین می کند. طرح رمزگذاری از یک الگوریتم HMAC کلیددار برای تولید یک صفحه مخفی بر اساس شناسه رویداد منحصر به فرد قالب استفاده می کند.

قیمت رمزگذاری شده دارای طول ثابت 28 بایت است. از یک بردار اولیه 16 بایتی، 8 بایت متن رمزی و یک امضای یکپارچگی 4 بایتی تشکیل شده است. طبق RFC 3548، قیمت رمزگذاری شده با پایه 64 ایمن وب کدگذاری شده است و کاراکترهای padding حذف شده است. بنابراین، قیمت رمزگذاری شده 28 بایتی بدون در نظر گرفتن قیمت برنده پرداخت شده، به عنوان یک رشته 38 کاراکتری ایمن وب پایه-64 رمزگذاری می شود.

نمونه قیمت های رمزگذاری شده:

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

فرمت رمزگذاری شده این است:

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

قیمت به صورت <price xor HMAC(encryption_key, initialization_vector)> رمزگذاری شده است، بنابراین رمزگشایی HMAC(encryption_key,initialization_vector) و xor را با قیمت رمزگذاری شده محاسبه می کند تا رمزگذاری معکوس شود. مرحله یکپارچگی 4 بایت از <HMAC(integrity_key, price||initialization_vector)> طول می کشد که در آن || الحاق است.

ورودی ها
iv بردار اولیه (16 بایت - منحصر به فرد برای قالب)
e_key کلید رمزگذاری (32 بایت - ارائه شده در راه اندازی حساب)
i_key کلید یکپارچگی (32 بایت - ارائه شده در راه اندازی حساب)
price (8 بایت - در میکرو واحد پول حساب)
نشانه گذاری
hmac(k, d) SHA-1 HMAC داده d با استفاده از کلید k
a || b رشته a ملحق شده با رشته b
شبه کد
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 )

طرح رمزگشایی

کد رمزگشایی شما باید قیمت را با استفاده از کلید رمزگشایی رمزگشایی کند و بیت‌های یکپارچگی را با کلید یکپارچگی تأیید کند. کلیدها در حین نصب در اختیار شما قرار خواهند گرفت. هیچ محدودیتی در جزئیات نحوه ساختار اجرای خود وجود ندارد. در بیشتر موارد، شما باید بتوانید کد نمونه را بگیرید و آن را مطابق با نیاز خود تطبیق دهید.

ورودی ها
e_key کلید رمزگذاری، 32 بایت - ارائه شده در راه اندازی حساب
i_key کلید یکپارچگی، 32 بایت - ارائه شده در راه اندازی حساب
final_message 38 کاراکتر وب ایمن base64 رمزگذاری شده است
شبه کد
// 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)

حملات پاسخ قدیمی را شناسایی کنید

برای شناسایی پاسخ‌های قدیمی، یا پخش مجدد حملات، توصیه می‌شود پس از محاسبه تفاوت‌های منطقه زمانی، پاسخ‌ها را با مهر زمانی فیلتر کنید که به طور قابل‌توجهی با زمان سیستم متفاوت است.

بردار مقداردهی اولیه شامل یک مهر زمانی در 8 بایت اول است. با تابع 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)
}

مهر زمانی را می توان با استفاده از کد 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);

کتابخانه جاوا

به جای پیاده سازی الگوریتم های رمزنگاری برای رمزگذاری و رمزگشایی قیمت برنده، می توانید از DoubleClickCrypto.java استفاده کنید. برای اطلاعات بیشتر، رمزنگاری را ببینید.