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

เมื่อครีเอทีฟโฆษณาชนะการประมูล 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} ไว้ใน VAST URL ของครีเอทีฟโฆษณาวิดีโอได้ด้วย แต่ไม่ใส่ไว้ใน 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. บนเซิร์ฟเวอร์ แอปพลิเคชันจะถอดรหัสฐาน 64 ที่ปลอดภัยบนเว็บเพื่อถอดรหัสข้อมูลราคาที่ชนะและถอดรหัสผลลัพธ์

แท็กเริ่มการทำงาน

คุณจะต้องมีไลบรารีการเข้ารหัสที่รองรับ SHA-1 HMAC เช่น ossl

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

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

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

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

การเข้ารหัส

การเข้ารหัสและการถอดรหัสราคาที่ชนะต้องใช้คีย์ลับ 2 คีย์ที่ใช้ร่วมกัน คีย์ความสมบูรณ์และคีย์การเข้ารหัส ซึ่งเรียกว่า i_key และ e_key ตามลำดับ คุณจะระบุคีย์ทั้ง 2 รายการได้ในการตั้งค่าบัญชีในรูปแบบสตริง 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 โดยไม่มีอักขระการเติม ดังนั้น ระบบจะเข้ารหัสราคาที่เข้ารหัส 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 กับราคาที่เข้ารหัสเพื่อถอดรหัส ระยะความสมบูรณ์ใช้ 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 แทนการใช้อัลกอริทึมการเข้ารหัสเพื่อเข้ารหัสและถอดรหัสราคาที่ชนะ ดูข้อมูลเพิ่มเติมได้ที่วิทยาการเข้ารหัส