ถอดรหัสการยืนยันราคา

เมื่อครีเอทีฟโฆษณาชนะการประมูล Google จะแจ้งให้คุณทราบถึงผู้ชนะ ราคาคือเมื่อครีเอทีฟโฆษณามีมาโครที่เกี่ยวข้อง

หากมีการกำหนดค่าโปรแกรมเสนอราคาให้ใช้โปรโตคอล OpenRTB ครีเอทีฟโฆษณา ที่รวมอยู่ในราคาเสนอควรใช้${AUCTION_PRICE}ของ IAB มาโคร

หากผู้เสนอราคาของคุณใช้โปรโตคอล RTB ของ Google ที่เลิกใช้งานแล้ว โฆษณาควร ใช้ %%WINNING_PRICE%% ของ Google มาโคร

เมื่อขยายมาโครเหล่านี้ มาโครจะแสดงราคาที่ชนะใน ที่เข้ารหัส มิติข้อมูลเหล่านี้สามารถรวมอยู่ในครีเอทีฟโฆษณา เช่น คำขอพิกเซลที่มองไม่เห็นที่แสดงผลเป็นส่วนหนึ่งของโฆษณา:

<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} ไว้ใน VAST URL ของ ครีเอทีฟโฆษณาวิดีโอ แต่ไม่อยู่ใน URL การแสดงผลใน VAST

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

สถานการณ์

  1. แอปพลิเคชันการเสนอราคา OpenRTB ของคุณมี ${AUCTION_PRICE} ในข้อมูลโค้ด HTML หรือ VAST URL ที่กลับไปยัง Google
  2. Google แทนที่ราคาที่ชนะสำหรับมาโครในอุปกรณ์ที่ปลอดภัยสำหรับเว็บแบบไม่มีอักขระแทรก การเข้ารหัส base64 (RFC 3548)
  3. ข้อมูลโค้ดผ่านการยืนยันในรูปแบบที่คุณเลือก สำหรับ ตัวอย่างเช่น อาจมีการส่งการยืนยันใน URL ของพิกเซลที่มองไม่เห็น ที่แสดงผลเป็นส่วนหนึ่งของโฆษณา
  4. บนเซิร์ฟเวอร์ แอปพลิเคชัน Web-safe base64 จะถอดรหัสราคาที่ชนะ และถอดรหัสผลลัพธ์ได้

การอ้างอิง

คุณจะต้องมีไลบรารีคริปโตที่รองรับ SHA-1 HMAC เช่น Openssl

โค้ดตัวอย่าง

โค้ดตัวอย่างมีให้ใน Java และ C++ และสามารถดาวน์โหลดได้จาก privatedatacommunicationprotocol โปรเจ็กต์

  • โค้ดตัวอย่างของ Java ใช้ตัวถอดรหัส base64 จาก Apache คอมมอนส์ คุณไม่จำเป็นต้องดาวน์โหลดโค้ด Apache Commons เนื่องจากการใช้การอ้างอิงรวมส่วนที่จำเป็นเอาไว้ และดังนั้นจึง จบในตัว

  • โค้ดตัวอย่าง C++ ใช้ OpenSSL เมธอด base64 BIO นำสตริงที่เข้ารหัสแบบ Web-safe base64 (RFC 3548) แล้วถอดรหัส โดยปกติแล้ว สตริง base64 สำหรับ Web-safe จะแทนที่ "=" ระยะห่างจากขอบด้วย "." (โปรดทราบว่า เครื่องหมายคำพูดจะถูกเพิ่มเพื่อความชัดเจนในการอ่าน และจะไม่รวมอยู่ใน ) แต่การแทนที่มาโครไม่ได้แพดราคาที่เข้ารหัส การใช้การอ้างอิงจะเพิ่มระยะห่างจากขอบเนื่องจาก OpenSSL มีปัญหากับ สตริงที่ไม่มีอักขระแทรก

การเข้ารหัส

การเข้ารหัสและถอดรหัสราคาที่ชนะต้องใช้ข้อมูลลับ 2 รายการ แต่ต้องมีการแชร์ คีย์ คีย์ความสมบูรณ์และคีย์การเข้ารหัสที่เรียกว่า i_key และ e_key ตามลำดับ คีย์ทั้ง 2 คีย์มีให้ในขั้นตอนการสร้างบัญชีเป็น Web-safe base64 แบบอื่นๆ และแสดงได้ในหน้า Authorized Buyers ภายใต้ ผู้เสนอราคา การตั้งค่า > การตั้งค่า RTB > คีย์การเข้ารหัส

ตัวอย่างคีย์ความสมบูรณ์และคีย์การเข้ารหัส

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

คีย์ควรได้รับการถอดรหัสแบบ Web-safe แล้วถอดรหัส base64 โดย แอปพลิเคชัน:

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

รูปแบบการเข้ารหัส

ราคาจะเข้ารหัสโดยใช้รูปแบบการเข้ารหัสที่กำหนดเองซึ่งออกแบบมา ลดค่าใช้จ่ายสิ้นเปลืองของขนาดไปพร้อมกับการรักษาความปลอดภัยที่เพียงพอ รูปแบบการเข้ารหัส ใช้อัลกอริทึม HMAC ที่ผูกกับคีย์เพื่อสร้างคีย์ลับ โดยอิงตามแท็ก รหัสเหตุการณ์การแสดงผล

ราคาที่เข้ารหัสมีความยาวคงที่ 28 ไบต์ ซึ่งประกอบด้วย เวกเตอร์การเริ่มต้น 16 ไบต์, ข้อความเข้ารหัส 8 ไบต์ และความสมบูรณ์แบบ 4 ไบต์ ลายเซ็น ราคาที่เข้ารหัสจะเข้ารหัสแบบ Web-safe base64 ตาม RFC 3548 ไม่มีการใส่อักขระ Padding ดังนั้น ราคาที่เข้ารหัส 28 ไบต์จะเป็น มีการเข้ารหัสเป็นสตริง 38 อักขระ Web-safe base-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 อักขระ Web-safe 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. สำหรับข้อมูลเพิ่มเติม โปรดดู วิทยาการเข้ารหัสลับ