หากผู้เผยแพร่โฆษณาส่งข้อมูลตําแหน่งของอุปกรณ์เคลื่อนที่ไปยัง Authorized Buyers ซึ่งมีความเจาะจงมากกว่ารหัสไปรษณีย์ Authorized Buyers จะส่งเขตพื้นที่เสมือน ##39;hyperlocal' ไปยังผู้ซื้อในช่องที่เข้ารหัสใหม่: BidRequest.encrypted_hyperlocal_set
ไทม์ไลน์
- ผู้ใช้ติดตั้งแอปบนอุปกรณ์เคลื่อนที่ที่มีโฆษณาสนับสนุน และให้ความยินยอมแก่แอปในการเข้าถึงและแชร์ตําแหน่งของอุปกรณ์กับบุคคลที่สาม แอปนี้ยังผสานรวมกับ SDK โฆษณา Google และส่งตําแหน่งอุปกรณ์นี้ไปยัง Google ด้วย
- เซิร์ฟเวอร์ของ Google จะสร้างสัญญาณการกําหนดเป้าหมายแบบเจาะจงพื้นที่พิเศษที่บ่งบอกถึงเขตพื้นที่เสมือนรอบตําแหน่งอุปกรณ์ เช่น เพื่อปกป้องความเป็นส่วนตัวของผู้ใช้
- เซิร์ฟเวอร์ของ Google จะเรียงลําดับและเข้ารหัสสัญญาณการกําหนดเป้าหมายแบบเจาะจงพื้นที่โดยใช้คีย์ความปลอดภัยสําหรับผู้ซื้อแต่ละรายโดยเฉพาะ โปรดทราบว่าผู้เสนอราคาจะใช้คีย์เดียวกันในการถอดรหัสมาโคร WINning_PRICE
- ผู้เสนอราคาจะถอดรหัสและแยกอนุกรมสัญญาณการกําหนดเป้าหมายแบบเจาะจงพื้นที่ไปยังบัฟเฟอร์โปรโตคอล จากนั้นผู้เสนอราคาจะสามารถวิเคราะห์สัญญาณและเสนอราคาให้สอดคล้องกันได้
การอ้างอิง
คุณจะต้องใช้ไลบรารีคริปโตที่รองรับ SHA-1 HMAC เช่น Openssl
คำจำกัดความ
สัญญาณการกําหนดเป้าหมายแบบเจาะจงพื้นที่มีคําจํากัดความในโปรโตทเช่นนี้
// A hyperlocal targeting location when available. // message Hyperlocal { // A location on the Earth's surface. // message Point { optional float latitude = 1; optional float longitude = 2; } // The mobile device can be at any point inside the geofence polygon defined // by a list of corners. Currently, the polygon is always a parallelogram // with 4 corners. repeated Point corners = 1; } message HyperlocalSet { // This field currently contains at most one hyperlocal polygon. repeated Hyperlocal hyperlocal = 1; // The approximate geometric center of the geofence area. It is calculated // exclusively based on the geometric shape of the geofence area and in no // way indicates the mobile device's actual location within the geofence // area. If multiple hyperlocal polygons are specified above then // center_point is the geometric center of all hyperlocal polygons. optional Hyperlocal.Point center_point = 2; } // Hyperlocal targeting signal when available, encrypted as described at // https://developers.google.com/authorized-buyers/rtb/response-guide/decrypt-hyperlocal optional bytes encrypted_hyperlocal_set = 40;
สัญญาณการกําหนดเป้าหมายแบบเจาะจงพื้นที่แต่ละรายการประกอบด้วยรูปหลายเหลี่ยมอย่างน้อย 1 จุดและจุดศูนย์กลาง สําหรับแต่ละรูปหลายเหลี่ยม สัญญาณการกําหนดเป้าหมายแบบเจาะจงพื้นที่จะประกอบด้วยข้อมูลต่อไปนี้
- ละติจูดและลองจิจูดของมุมแต่ละมุมของรูปหลายเหลี่ยมตามลําดับจะส่งผ่านช่อง
corners
ที่ซ้ํากัน - ศูนย์กลางเรขาคณิตโดยประมาณของพื้นที่เขตพื้นที่เสมือน ที่ส่งผ่านในช่อง
center_point
ที่ไม่บังคับ
โครงสร้างของสัญญาณการกําหนดเป้าหมาย
สัญญาณการกําหนดเป้าหมายแบบเจาะจงพื้นที่ที่เข้ารหัสใน BidRequest.encrypted_hyperlocal_set
ประกอบด้วย 3 ส่วนดังนี้
initialization_vector
: 16 ไบต์ciphertext
: ชุดส่วน 20 ไบต์integrity_signature
: 4 ไบต์
{initialization_vector (16 bytes)}{ciphertext (20-byte sections)}{integrity_signature (4 bytes)}
อาร์เรย์ ciphertext
ไบต์แบ่งออกเป็นหลายส่วนขนาด 20 ไบต์ โดยมีข้อยกเว้นว่าส่วนสุดท้ายอาจมีเพียง 1 ถึง 20 ไบต์ ciphertext
ขนาด 20 ไบต์ที่เกี่ยวข้องจะสร้างแต่ละส่วนของ byte_array
ต้นฉบับ ในรูปแบบต่อไปนี้
<byte_array <xor> HMAC(encryption_key, initialization_vector || counter_bytes)>
ที่ ||
คือการเชื่อมโยง
คำจำกัดความ
ตัวแปร | รายละเอียด |
---|---|
initialization_vector |
16 ไบต์ - ไม่ซ้ํากันสําหรับการแสดงผล |
encryption_key |
32 ไบต์ - มีให้เมื่อสร้างบัญชี |
integrity_key |
32 ไบต์ - มีให้เมื่อสร้างบัญชี |
byte_array |
ออบเจ็กต์ที่เรียงตามลําดับใน HyperlocalSet ในส่วน 20 ไบต์ |
counter_bytes |
ค่าไบต์ที่แสดงจํานวนเลขลําดับของส่วน โปรดดูด้านล่าง |
final_message |
อาร์เรย์ไบต์ที่ส่งผ่านทางช่อง BidRequest.encrypted_hyperlocal_set |
โอเปอเรเตอร์ | รายละเอียด |
---|---|
hmac(key, data) |
SHA-1 HMAC ใช้ key เพื่อเข้ารหัส data |
a || b |
สตริง a ที่ต่อด้วยสตริง b |
คํานวณจํานวนตัวนับ
counter_bytes
กํากับลําดับของส่วน 20 ไบต์แต่ละรายการของ ciphertext
โปรดทราบว่าส่วนสุดท้ายอาจประกอบด้วยข้อมูลขนาด 1 ถึง 20 ไบต์ หากต้องการใส่ counter_bytes
ด้วยค่าที่ถูกต้อง
เมื่อเรียกใช้ฟังก์ชัน hmac()
ให้นับส่วน 20 ไบต์
(รวมทั้งที่เหลือ) และใช้ตารางอ้างอิงต่อไปนี้
หมายเลขส่วน | มูลค่า counter_bytes |
---|---|
0 | ไม่มี |
1 ... 256 | 1 ไบต์ ค่าจะเพิ่มขึ้นจาก 0 ถึง 255 ตามลําดับ |
257 ... 512 | 2 ไบต์ ค่าไบต์แรกคือ 0 ค่าไบต์ที่ 2 เพิ่มขึ้นจาก 0 ถึง 255 ตามลําดับ |
513 ... 768 | 3 ไบต์ ค่า 2 ไบต์แรกคือ 0 และค่าของไบต์สุดท้ายเพิ่มขึ้นจาก 0 เป็น 255 ตามลําดับ |
เราไม่คาดหวังความยาวของ BidRequest.encrypted_hyperlocal_set
ที่เกิน 1 กิโลไบต์ แม้แต่ในการขยายธุรกิจให้เติบโตยิ่งขึ้นไปอีก แต่ counter_bytes
อาจมีความยาวเท่าที่จําเป็นเพื่อรองรับสัญญาณการกําหนดเป้าหมายแบบเจาะจงพื้นที่ที่มีระยะเวลาจํากัด
รูปแบบการเข้ารหัส
รูปแบบการเข้ารหัสสําหรับสัญญาณการกําหนดเป้าหมายแบบเจาะจงพื้นที่จะขึ้นอยู่กับแบบแผนเดียวกับที่ใช้สําหรับการถอดรหัสการยืนยันราคา
Serialization: สัญญาณการกําหนดเป้าหมายแบบเจาะจงพื้นที่ซึ่งเป็นอินสแตนซ์ของออบเจ็กต์ HyperlocalSet ตามที่กําหนดไว้ในโปรโตคอล จะได้รับการจัดลําดับผ่าน
SerializeAsString()
ไปยังอาร์เรย์ไบต์ก่อนการเข้ารหัส: อาร์เรย์ไบต์จะได้รับการเข้ารหัสโดยใช้รูปแบบการเข้ารหัสที่กําหนดเองซึ่งออกแบบมาเพื่อลดขนาดค่าใช้จ่ายให้เหลือน้อยที่สุด พร้อมทั้งรักษาความปลอดภัยให้เพียงพอ สคีมการเข้ารหัสจะใช้อัลกอริทึม HMAC ที่มีคีย์ในการสร้างแพดข้อมูลลับโดยอิงตาม
initialization_vector
ซึ่งเป็นเหตุการณ์ที่ไม่ซ้ําโดยเฉพาะ
ซูโดโค้ดการเข้ารหัส
byte_array = SerializeAsString(HyperlocalSet object) pad = hmac(encryption_key, initialization_vector || counter_bytes ) // for each 20-byte section of byte_array ciphertext = pad <xor> byte_array // for each 20-byte section of byte_array integrity_signature = hmac(integrity_key, byte_array || initialization_vector) // first 4 bytes final_message = initialization_vector || ciphertext || integrity_signature
แผนถอดรหัส
โค้ดการถอดรหัสของคุณต้อง 1) ถอดรหัสสัญญาณการกําหนดเป้าหมายแบบเจาะจงพื้นที่โดยใช้คีย์การเข้ารหัส และ 2) ยืนยันบิตสมบูรณ์ด้วยคีย์ความสมบูรณ์ คุณจะได้รับคีย์ในระหว่างการตั้งค่าบัญชี ไม่มีข้อจํากัดใดๆ เกี่ยวกับวิธีการจัดโครงสร้างการติดตั้งใช้งาน ในกรณีส่วนใหญ่ คุณควรสามารถนําโค้ดตัวอย่างไปปรับใช้ตามความต้องการได้
- สร้างแพด:
HMAC(encryption_key, initialization_vector || counter_bytes)
- XOR: ดูผลการค้นหานี้และ
<xor>
พร้อมกับข้อความเข้ารหัสเพื่อย้อนการเข้ารหัส - ยืนยัน: ลายเซ็นความสมบูรณ์จะส่งผ่าน
HMAC(integrity_key, byte_array || initialization_vector)
ขนาด 4 ไบต์
การถอดรหัสแบบ Pseudocode
(initialization_vector, ciphertext, integrity_signature) = final_message // split up according to length rules pad = hmac(encryption_key, initialization_vector || counter_bytes) // for each 20-byte section of ciphertext byte_array = ciphertext <xor> pad // for each 20-byte section of ciphertext confirmation_signature = hmac(integrity_key, byte_array || initialization_vector) success = (confirmation_signature == integrity_signature)
ตัวอย่างโค้ด C++
ในตัวอย่างนี้เป็นฟังก์ชันหลักจากโค้ดตัวอย่างการถอดรหัสที่สมบูรณ์ของเรา
bool DecryptByteArray( const string& ciphertext, const string& encryption_key, const string& integrity_key, string* cleartext) { // Step 1. find the length of initialization vector and clear text. const int cleartext_length = ciphertext.size() - kInitializationVectorSize - kSignatureSize; if (cleartext_length < 0) { // The length cannot be correct. return false; } string iv(ciphertext, 0, kInitializationVectorSize); // Step 2. recover clear text cleartext->resize(cleartext_length, '\0'); const char* ciphertext_begin = string_as_array(ciphertext) + iv.size(); const char* const ciphertext_end = ciphertext_begin + cleartext->size(); string::iterator cleartext_begin = cleartext->begin(); bool add_iv_counter_byte = true; while (ciphertext_begin < ciphertext_end) { uint32 pad_size = kHashOutputSize; uchar encryption_pad[kHashOutputSize]; if (!HMAC(EVP_sha1(), string_as_array(encryption_key), encryption_key.length(), (uchar*)string_as_array(iv), iv.size(), encryption_pad, &pad_size)) { printf("Error: encryption HMAC failed.\n"); return false; } for (int i = 0; i < kBlockSize && ciphertext_begin < ciphertext_end; ++i, ++cleartext_begin, ++ciphertext_begin) { *cleartext_begin = *ciphertext_begin ^ encryption_pad[i]; } if (!add_iv_counter_byte) { char& last_byte = *iv.rbegin(); ++last_byte; if (last_byte == '\0') { add_iv_counter_byte = true; } } if (add_iv_counter_byte) { add_iv_counter_byte = false; iv.push_back('\0'); } } }
ตัวอย่างสัญญาณและคีย์เฉพาะพื้นที่
หากต้องการทดสอบและยืนยันรหัส ให้ทําดังนี้
- แปลงสตริงที่มีอักขระฐานสิบหก 308 ตัวเป็นอาร์เรย์ 154 ไบต์ เช่น สําหรับสตริงต่อไปนี้
E2014EA201246E6F6E636520736F7572636501414243C0ADF6B9B6AC17DA218FB50331EDB376701309CAAA01246E6F6E636520736F7572636501414243C09ED4ECF2DB7143A9341FDEFD125D96844E25C3C202466E6F6E636520736F7572636502414243517C16BAFADCFAB841DE3A8C617B2F20A1FB7F9EA3A3600256D68151C093C793B0116DB3D0B8BE9709304134EC9235A026844F276797
แปลงเป็นอาร์เรย์ 154 ไบต์ดังนี้const char serialized_result[154] = { 0xE2, 0x01, 0x4E, ... };
- เรียกเมธอด
BidRequest.ParsePartialFromString()
เพื่อเปลี่ยนลําดับอาร์เรย์ 154 ไบต์เป็นบัฟเฟอร์โปรโตคอลBidRequest
BidRequest bid_req; bid_req.ParsePartialFromString(serialzed_result);
- ตรวจสอบว่า
BidRequest
มีช่องเพียง 3 ช่องดังนี้encrypted_hyperlocal_set
ประกาศในข้อความBidReqeust
encrypted_advertising_id
ประกาศในข้อความBidReqeust.Mobile
encrypted_hashed_idfa
ประกาศในข้อความBidReqeust.Mobile
เช่น
encrypted_hyperlocal_set:( { 100, 100 }, { 200, -300 }, { -400, 500 }, { -600, -700 },) encrypted_advertising_id: { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 } encrypted_hashed_idfa : { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xF1 }
- ใช้
encryption_key
และintegrity_key
ต่อไปนี้เพื่อถอดรหัส 3 ช่องและยืนยันว่าคุณถอดรหัสอย่างถูกต้องencryption_key = {0x02, 0xEE, 0xa8, 0x3c, 0x6c, 0x12, 0x11, 0xe1, 0x0b, 0x9f, 0x88, 0x96, 0x6c, 0xee, 0xc3, 0x49, 0x08, 0xeb, 0x94, 0x6f, 0x7e, 0xd6, 0xe4, 0x41, 0xaf, 0x42, 0xb3, 0xc0, 0xf3, 0x21, 0x81, 0x40}; integrity_key = {0xbf, 0xFF, 0xec, 0x55, 0xc3, 0x01, 0x30, 0xc1, 0xd8, 0xcd, 0x18, 0x62, 0xed, 0x2a, 0x4c, 0xd2, 0xc7, 0x6a, 0xc3, 0x3b, 0xc0, 0xc4, 0xce, 0x8a, 0x3d, 0x3b, 0xbd, 0x3a, 0xd5, 0x68, 0x77, 0x92};
ตรวจจับการโจมตีที่ไม่มีการอัปเดต
เราขอแนะนําให้ตรวจหาการตอบกลับที่มีการประทับเวลาซึ่งมีเวลาแตกต่างจากเวลาของระบบอย่างมาก หลังจากตรวจพบความแตกต่างของเขตเวลาหลังจากเกิดการโจมตีที่ไม่มีอัปเดต เซิร์ฟเวอร์ของเราตั้งค่าไว้เป็น PST/PDT
โปรดดูรายละเอียดการนําไปใช้งานใน "การตรวจหาการโจมตีในการตอบกลับที่ไม่มีการอัปเดต" ในบทความการถอดรหัสการยืนยันราคา
ไลบรารี Java
แทนที่จะใช้อัลกอริทึมคริปโตเพื่อเข้ารหัสและถอดรหัสสัญญาณการกําหนดเป้าหมายแบบเจาะจงพื้นที่ คุณสามารถใช้ DoubleClickCrypto.java ดูข้อมูลเพิ่มเติมได้ที่การเข้ารหัสลับ