رمزگشایی شناسه های تبلیغ کننده برای شبکه های تبلیغاتی

شبکه‌های تبلیغاتی که از برچسب‌های جاوا اسکریپت برای پر کردن تبلیغات از طریق خریداران مجاز استفاده می‌کنند، واجد شرایط دریافت شناسه‌های تبلیغ‌کننده برای دستگاه‌های Android و iOS هستند. اطلاعات از طریق %%EXTRA_TAG_DATA%% یا %%ADVERTISING_IDENTIFIER%% ماکرو در برچسب جاوا اسکریپت که توسط خریداران مجاز مدیریت می‌شود ارسال می‌شود. بقیه این بخش بر استخراج %%EXTRA_TAG_DATA%% تمرکز دارد، اما برای جزئیات بیشتر در مورد %%ADVERTISING_IDENTIFIER%% بافر پروتو رمزگذاری شده MobileAdvertisingId که می تواند به طور مشابه رمزگشایی شود ، بازاریابی مجدد با IDFA یا شناسه تبلیغاتی را ببینید.

جدول زمانی

  1. شبکه تبلیغاتی تگ‌های درون برنامه‌ای جاوا اسکریپت خود را از طریق رابط کاربری مجاز خریداران به‌روزرسانی می‌کند و ماکرو %%EXTRA_TAG_DATA%% را همانطور که در زیر توضیح داده شده اضافه می‌کند.
  2. در زمان ارائه، برنامه از خریداران مجاز از طریق Google Mobile Ads SDK آگهی درخواست می‌کند، در حالی که شناسه آگهی‌دهنده را به‌طور ایمن ارسال می‌کند.
  3. برنامه تگ جاوا اسکریپت را با %%EXTRA_TAG_DATA%% ماکرو که با بافر پروتکل شبکه تبلیغات رمزگذاری شده حاوی آن شناسه پر شده است، دریافت می کند.
  4. برنامه این تگ را اجرا می کند و برای تبلیغ برنده با شبکه تبلیغات تماس می گیرد.
  5. به منظور استفاده (کسب درآمد) از این اطلاعات، شبکه تبلیغاتی باید بافر پروتکل را پردازش کند:
    1. با WebSafeBase64 رشته websafe را دوباره به یک بایت تست رمزگشایی کنید.
    2. با استفاده از طرح زیر آن را رمزگشایی کنید.
    3. پروتو را از حالت سریال خارج کنید و شناسه تبلیغ کننده را از ExtraTagData.advertising_id یا ExtraTagData.hashed_idfa دریافت کنید.

وابستگی ها

  1. رمزگذار WebSafeBase64 .
  2. یک کتابخانه رمزنگاری که از SHA-1 HMAC پشتیبانی می کند، مانند Openssl .
  3. کامپایلر بافر پروتکل گوگل .

رمزگشایی رشته وب ایمن

از آنجا که اطلاعات ارسال شده از طریق %%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(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 افزایش می یابد.

بازگشت به بالا

طرح رمزگذاری

طرح رمزگذاری بر اساس همان طرحی است که برای رمزگشایی سیگنال هدف گیری هایپرمحلی استفاده می شود.

  1. Serialization : نمونه ای از شی ExtraTagData همانطور که در بافر پروتکل تعریف شده است ابتدا از طریق SerializeAsString() به یک آرایه بایت سریال می شود.

  2. رمزگذاری : سپس آرایه بایت با استفاده از یک طرح رمزگذاری سفارشی که برای به حداقل رساندن حجم سربار طراحی شده و در عین حال امنیت کافی را تضمین می کند، رمزگذاری می شود. طرح رمزگذاری از یک الگوریتم 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) بیت های یکپارچگی را با کلید یکپارچگی تأیید کند. کلیدها در حین تنظیم حساب در اختیار شما قرار خواهند گرفت. هیچ محدودیتی در نحوه ساختار پیاده سازی شما وجود ندارد. در بیشتر موارد، شما باید بتوانید کد نمونه را بگیرید و آن را مطابق با نیاز خود تطبیق دهید.

  1. پد خود را ایجاد کنید : HMAC(encryption_key, initialization_vector || counter_bytes)
  2. XOR : این نتیجه را بگیرید و <xor> با متن رمزگذاری کنید تا رمزگذاری معکوس شود.
  3. تأیید کنید : امضای یکپارچگی 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 استفاده کنید. برای اطلاعات بیشتر، رمزنگاری را ببینید.