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

عندما يفوز تصميم إعلانك بمزاد، يمكن أن تُعلمك Google بالسعر الفائز إذا كان تصميم الإعلان يتضمّن وحدة الماكرو ${AUCTION_PRICE}.

عند توسيع وحدة الماكرو، يتم عرض السعر الفائز في شكل مُشفَّر. ويمكن تضمينه في تصميم إعلان، على سبيل المثال، من خلال طلب بكسل غير مرئي يتم عرضه كجزء من الإعلان:

<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} في عنوان URL الخاص بتنسيق VAST لتصاميم إعلانات الفيديو، ولكن ليس في عنوان URL لموضع الإعلان في تنسيق VAST:

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

السيناريو

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

التبعيات

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

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

يتم توفير نموذج الرمز البرمجي بلغتَي Java وC++‎، ويمكن تنزيله من project privatedatacommunicationprotocol.

  • يستخدم نموذج الرمز البرمجي في Java أداة فك ترميز base64 من مشروع Apache commons. لن تحتاج إلى تنزيل رمز Apache commons، لأنّ التنفيذ المرجعي يتضمّن الجزء الضروري وبالتالي هو مكتفٍ ذاتيًا.

  • يستخدم نموذج الرمز البرمجي بلغة 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 بايت كسلسلة base-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 مع السعر المشفَّر لعكس التشفير. تستغرق مرحلة السلامة 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);

مكتبة Java

بدلاً من تنفيذ خوارزميات التشفير لتشفير السعر الفائز وفك تشفيره، يمكنك استخدام DoubleClickCrypto.java. لمزيد من المعلومات، يُرجى الاطّلاع على التشفير.