شبکههای تبلیغاتی که از برچسبهای جاوا اسکریپت برای پر کردن تبلیغات از طریق خریداران مجاز استفاده میکنند، واجد شرایط دریافت شناسههای تبلیغکننده برای دستگاههای Android و iOS هستند. اطلاعات از طریق %%EXTRA_TAG_DATA%%
یا %%ADVERTISING_IDENTIFIER%%
ماکرو در برچسب جاوا اسکریپت که توسط خریداران مجاز مدیریت میشود ارسال میشود. بقیه این بخش بر استخراج %%EXTRA_TAG_DATA%%
تمرکز دارد، اما برای جزئیات بیشتر در مورد %%ADVERTISING_IDENTIFIER%%
بافر پروتو رمزگذاری شده MobileAdvertisingId
که می تواند به طور مشابه رمزگشایی شود ، بازاریابی مجدد با IDFA یا شناسه تبلیغاتی را ببینید.
جدول زمانی
- شبکه تبلیغاتی تگهای درون برنامهای جاوا اسکریپت خود را از طریق رابط کاربری مجاز خریداران بهروزرسانی میکند و ماکرو
%%EXTRA_TAG_DATA%%
را همانطور که در زیر توضیح داده شده اضافه میکند. - در زمان ارائه، برنامه از خریداران مجاز از طریق Google Mobile Ads SDK آگهی درخواست میکند، در حالی که شناسه آگهیدهنده را بهطور ایمن ارسال میکند.
- برنامه تگ جاوا اسکریپت را با
%%EXTRA_TAG_DATA%%
ماکرو که با بافر پروتکل شبکه تبلیغات رمزگذاری شده حاوی آن شناسه پر شده است، دریافت می کند. - برنامه این تگ را اجرا می کند و برای تبلیغ برنده با شبکه تبلیغات تماس می گیرد.
- به منظور استفاده (کسب درآمد) از این اطلاعات، شبکه تبلیغاتی باید بافر پروتکل را پردازش کند:
- با WebSafeBase64 رشته websafe را دوباره به یک بایت تست رمزگشایی کنید.
- با استفاده از طرح زیر آن را رمزگشایی کنید.
- پروتو را از حالت سریال خارج کنید و شناسه تبلیغ کننده را از ExtraTagData.advertising_id یا ExtraTagData.hashed_idfa دریافت کنید.
وابستگی ها
- رمزگذار WebSafeBase64 .
- یک کتابخانه رمزنگاری که از SHA-1 HMAC پشتیبانی می کند، مانند Openssl .
- کامپایلر بافر پروتکل گوگل .
رشته وب ایمن را رمزگشایی کنید
از آنجا که اطلاعات ارسال شده از طریق %%EXTRA_TAG_DATA%%
ماکرو باید از طریق URL ارسال شود، سرورهای Google آن را با web-safe base64 ( RFC 3548 ) رمزگذاری میکنند.
بنابراین، قبل از تلاش برای رمزگشایی، باید کاراکترهای ASCII را به یک بایت تست رمزگشایی کنید. نمونه کد C++ زیر بر اساس () BIO_f_base64 پروژه OpenSSL است و بخشی از کد رمزگشایی نمونه Google است.
string AddPadding(const string& b64_string) { if (b64_string.size() % 4 == 3) { return b64_string + "="; } else if (b64_string.size() % 4 == 2) { return b64_string + "=="; } return b64_string; } // Adapted from http://www.openssl.org/docs/man1.1.0/crypto/BIO_f_base64.html // Takes a web safe base64 encoded string (RFC 3548) and decodes it. // Normally, web safe base64 strings have padding '=' replaced with '.', // but we will not pad the ciphertext. We add padding here because // openssl has trouble with unpadded strings. string B64Decode(const string& encoded) { string padded = AddPadding(encoded); // convert from web safe -> normal base64. int32 index = -1; while ((index = padded.find_first_of('-', index + 1)) != string::npos) { padded[index] = '+'; } index = -1; while ((index = padded.find_first_of('_', index + 1)) != string::npos) { padded[index] = '/'; } // base64 decode using openssl library. const int32 kOutputBufferSize = 256; char output[kOutputBufferSize]; BIO* b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); BIO* bio = BIO_new_mem_buf(const_cast<char*>(padded.data()), padded.length()); bio = BIO_push(b64, bio); int32 out_length = BIO_read(bio, output, kOutputBufferSize); BIO_free_all(bio); return string(output, out_length); }
ساختار بای تست رمزگذاری شده
هنگامی که کاراکترهای ASCII را دوباره در یک بایتسترینگ رمزگشایی کردید، آماده رمزگشایی آن هستید. بای تست رمزگذاری شده شامل 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 بایت را شامل شود. برای هر بخش از byte_array
اصلی، ciphertext
۲۰ بایتی مربوطه به صورت زیر تولید میشود:
<byte_array <xor> HMAC(encryption_key, initialization_vector || counter_bytes)>
کجا ||
الحاق است.
تعاریف
متغیر | جزئیات |
---|---|
initialization_vector | 16 بایت - منحصر به فرد برای برداشت. |
encryption_key | 32 بایت - ارائه شده در راه اندازی حساب. |
integrity_key | 32 بایت - ارائه شده در راه اندازی حساب. |
byte_array | یک شیء سریال ExtraTagData ، در بخش های 20 بایتی. |
counter_bytes | مقدار بایت که شماره ترتیبی بخش را نشان می دهد، به زیر مراجعه کنید. |
final_message | کل آرایه بایت ارسال شده از طریق %%EXTRA_TAG_DATA%% ماکرو (منهای رمزگذاری WebSafeBase64). |
اپراتورها | جزئیات |
---|---|
hmac(key, data) | SHA-1 HMAC، با استفاده از key برای رمزگذاری data . |
a || b | رشته a به رشته b پیوسته است. |
محاسبه counter_bytes
counter_bytes
ترتیب هر بخش 20 بایتی ciphertext
مشخص می کند. توجه داشته باشید که بخش آخر ممکن است شامل 1 تا 20 بایت باشد. برای پر کردن counter_bytes
با مقدار صحیح هنگام اجرای تابع hmac()
، بخش های 20 بایتی (از جمله بقیه) را بشمارید و از جدول مرجع زیر استفاده کنید:
شماره بخش | مقدار counter_bytes |
---|---|
0 | هیچ کدام |
1 … 256 | 1 بایت مقدار به صورت متوالی از 0 تا 255 افزایش می یابد. |
257 … 512 | 2 بایت مقدار بایت اول 0 است، مقدار بایت دوم به ترتیب از 0 تا 255 افزایش می یابد. |
513 … 768 | 3 بایت مقدار دو بایت اول 0 است، مقدار آخرین بایت به ترتیب از 0 تا 255 افزایش می یابد. |
طرح رمزگذاری
طرح رمزگذاری بر اساس همان طرحی است که برای رمزگشایی سیگنال هدف گیری هایپرمحلی استفاده می شود.
Serialization : نمونه ای از شی ExtraTagData همانطور که در بافر پروتکل تعریف شده است ابتدا از طریق
SerializeAsString()
به یک آرایه بایت سریال می شود.رمزگذاری : سپس آرایه بایت با استفاده از یک طرح رمزگذاری سفارشی که برای به حداقل رساندن حجم سربار طراحی شده و در عین حال امنیت کافی را تضمین می کند، رمزگذاری می شود. طرح رمزگذاری از یک الگوریتم HMAC کلیددار برای تولید یک صفحه مخفی بر اساس
initialization_vector
استفاده میکند که منحصر به رویداد impression است.
شبه رمزگذاری
byte_array = SerializeAsString(ExtraTagData 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>
با متن رمزگذاری کنید تا رمزگذاری معکوس شود. - تأیید کنید : امضای یکپارچگی 4 بایت
HMAC(integrity_key, byte_array || initialization_vector)
رمزگشایی شبه کد
// split up according to length rules (initialization_vector, ciphertext, integrity_signature) = final_message // for each 20-byte section of ciphertext pad = hmac(encryption_key, initialization_vector || counter_bytes) // for each 20-byte section of ciphertext byte_array = ciphertext <xor> pad 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'); } }
دادهها را از بافر پروتکل شبکه تبلیغاتی دریافت کنید
هنگامی که دادههای ارسال شده در %%EXTRA_TAG_DATA%%
را رمزگشایی و رمزگشایی کردید، آماده هستید تا بافر پروتکل را از حالت سریال خارج کنید و شناسه تبلیغکننده را برای هدفیابی دریافت کنید.
اگر با بافرهای پروتکل آشنا نیستید، با مستندات ما شروع کنید .
تعریف
بافر پروتکل شبکه تبلیغاتی ما به شرح زیر است:
message ExtraTagData { // advertising_id can be Apple's identifier for advertising (IDFA) // or Android's advertising identifier. When the advertising_id is an IDFA, // it is the plaintext returned by iOS's [ASIdentifierManager // advertisingIdentifier]. For hashed_idfa, the plaintext is the MD5 hash of // the IDFA. Only one of the two fields will be available, depending on the // version of the SDK making the request. Later SDKs provide unhashed values. optional bytes advertising_id = 1; optional bytes hashed_idfa = 2; }
شما باید آن را با استفاده از ParseFromString()
deserialize کنید، همانطور که در مستندات بافر پروتکل C++ توضیح داده شده است.
برای جزئیات بیشتر در مورد فیلدهای Android advertising_id
و iOS hashed_idfa
، به رمزگشایی شناسه تبلیغات و فهرست هدفگذاری برنامه تلفن همراه با IDFA مراجعه کنید.
کتابخانه جاوا
به جای اجرای الگوریتم های رمزنگاری برای رمزگذاری و رمزگشایی شناسه های تبلیغ کننده برای شبکه های تبلیغاتی، می توانید از DoubleClickCrypto.java استفاده کنید. برای اطلاعات بیشتر، رمزنگاری را ببینید.