تأكيدات فك التشفير

عندما يفوز تصميم إعلانك بمزاد، يمكن أن تُطلعك Google على السعر الفائز، إذا كان مقتطف 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) لتصميم إعلان فيديو (ولكن ليس في عنوان URL لمرات الظهور في نموذج عرض إعلانات الفيديو (VAST):

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

السيناريو

  1. يتضمّن تطبيقك وحدة الماكرو WINNING_PRICE في مقتطف HTML أو عنوان URL الخاص بنموذج عرض إعلانات الفيديو (VAST) الذي يتم عرضه على Google.
  2. تستبدل Google السعر الفائز لوحدة الماكرو في ترميز base64 غير مضاف آمن على الويب (RFC 3548).
  3. يمرر المقتطف التأكيد بالتنسيق الذي اخترته. على سبيل المثال، قد يتم تمرير التأكيد في عنوان URL لطلب بكسل غير مرئي يتم عرضه كجزء من الإعلان.
  4. على الخادم، يفكّ تطبيقك Base64 الآمن على الويب معلومات السعر الفائز وفك تشفير النتيجة.

التبعيات

ستحتاج إلى مكتبة عملات مشفّرة تتوافق مع خوارزمية SHA-1 HMAC، مثل Openssl.

نموذج التعليمات البرمجية

يتم توفير نموذج رمز برمجي بلغة Java وC++ ويمكن تنزيله من مشروع Privatedata الإعجابprotocol.

  • يستخدم نموذج رمز Java برنامج فك ترميز base64 من مشروع Apachecommons. ولن تحتاج إلى تنزيل رمز Apachecommons، لأن تنفيذ المرجع يتضمن الجزء الضروري، وبالتالي يكون مستقلاً.

  • يستخدم نموذج الرمز C++ طريقة OpenSSL base64 BIO. تستخدم هذه الطريقة سلسلة Base64 مرمّزة آمنة على الويب (RFC 3548) وفك ترميزها. عادةً ما تستبدل سلاسل Base64 الآمنة على الويب "=" مساحة متروكة بـ "." (ملاحظة: تتم إضافة علامات الاقتباس لتوضيح القراءة ولا يتم تضمينها في البروتوكول) ولكن لا يؤدي الاستبدال الكلي إلى السعر المشفّر. يضيف تطبيق المرجع مساحة متروكة لأنّ هناك مشكلة في OpenSSL مع السلاسل غير المضافة.

الترميز

يتطلب تشفير السعر الفائز وفك تشفيره مفتاحَين سريَين، ولكنهما مشتركان. مفتاح سلامة ومفتاح تشفير، يُشار إليهما باسم i_key وe_key على التوالي. يتم توفير كلا المفتاحَين عند إعداد الحساب كسلاسل base64 آمنة على الويب، ويمكن العثور عليهما في صفحة "الشراة المعتمَدون" ضمن إعدادات مقدِّم عروض الأسعار > إعدادات عرض الأسعار في الوقت الفعلي > مفاتيح التشفير.

أمثلة على مفاتيح التشفير والتحقّق من السلامة:

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 بايت. السعر المشفّر بترميز base64 آمن على الويب، وفقًا لمعيار RFC 3548، مع حذف أحرف المساحة المتروكة. وبالتالي، يتم ترميز السعر المشفَّر بتنسيق 28 بايت على أنّه سلسلة أساسية من 64 حرفًا متوافقة مع الويب الآمن من 38 حرفًا بغض النظر عن السعر الفائز المدفوع.

أمثلة على الأسعار المشفّرة:

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's باستخدام السعر المشفّر لإبطال التشفير. تستغرق مرحلة السلامة 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 تشفير base64 آمن لـ 38 حرفًا
رمز زائف
// 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. لمزيد من المعلومات، يمكنك الاطّلاع على التشفير.