বিজ্ঞাপন নেটওয়ার্কের জন্য বিজ্ঞাপনদাতা শনাক্তকারীকে ডিক্রিপ্ট করা

অনুমোদিত ক্রেতাদের মাধ্যমে বিজ্ঞাপনগুলি পূরণ করতে JavaScript ট্যাগ ব্যবহার করে বিজ্ঞাপন নেটওয়ার্কগুলি Android এবং iOS উভয় ডিভাইসের জন্য বিজ্ঞাপনদাতা শনাক্তকারী পাওয়ার যোগ্য৷ অনুমোদিত ক্রেতাদের দ্বারা পরিচালিত জাভাস্ক্রিপ্ট ট্যাগে %%EXTRA_TAG_DATA%% বা %%ADVERTISING_IDENTIFIER%% ম্যাক্রোর মাধ্যমে তথ্য পাঠানো হয়। এই বিভাগের বাকি অংশটি %%EXTRA_TAG_DATA%% এক্সট্রাক্ট করার উপর ফোকাস করে কিন্তু %%ADVERTISING_IDENTIFIER%% এনক্রিপ্ট করা প্রোটো বাফার MobileAdvertisingId এর বিশদ বিবরণের জন্য IDFA এর সাথে রিমার্কেটিং বা বিজ্ঞাপন আইডি দেখুন যা একইভাবে ডিক্রিপ্ট করা যেতে পারে।

টাইমলাইন

  1. বিজ্ঞাপন নেটওয়ার্ক তাদের জাভাস্ক্রিপ্ট ইন-অ্যাপ ট্যাগগুলিকে অনুমোদিত ক্রেতাদের UI এর মাধ্যমে আপডেট করে, %%EXTRA_TAG_DATA%% ম্যাক্রো যোগ করে যা নীচে ব্যাখ্যা করা হয়েছে৷
  2. পরিবেশন করার সময়, অ্যাপটি বিজ্ঞাপনদাতা শনাক্তকারীকে নিরাপদে পাস করার সময় Google মোবাইল বিজ্ঞাপন SDK-এর মাধ্যমে অনুমোদিত ক্রেতাদের কাছ থেকে একটি বিজ্ঞাপনের অনুরোধ করে।
  3. অ্যাপটি জাভাস্ক্রিপ্ট ট্যাগটি ফিরে পায়, %%EXTRA_TAG_DATA%% ম্যাক্রো এনক্রিপ্ট করা অ্যাড নেটওয়ার্ক প্রোটোকল বাফারের সাথে সেই শনাক্তকারীকে পূর্ণ করে৷
  4. অ্যাপটি এই ট্যাগটি চালায়, বিজয়ী বিজ্ঞাপনের জন্য বিজ্ঞাপন নেটওয়ার্কে একটি কল করে।
  5. এই তথ্য ব্যবহার (নগদীকরণ) করার জন্য, বিজ্ঞাপন নেটওয়ার্ককে অবশ্যই প্রোটোকল বাফার প্রক্রিয়া করতে হবে:
    1. WebSafeBase64 এর সাথে একটি বাইটেস্ট্রিং-এ ওয়েবসেফ স্ট্রিং ডিকোড করুন।
    2. নীচে বর্ণিত স্কিম ব্যবহার করে এটি ডিক্রিপ্ট করুন।
    3. প্রোটোকে ডিসিরিয়ালাইজ করুন এবং ExtraTagData.advertising_id বা ExtraTagData.hashed_idfa থেকে বিজ্ঞাপনদাতা আইডি পান।

নির্ভরতা

  1. WebSafeBase64 এনকোডার
  2. একটি ক্রিপ্টো লাইব্রেরি যা SHA-1 HMAC সমর্থন করে, যেমন Openssl
  3. গুগল প্রোটোকল বাফার কম্পাইলার

ওয়েবসেফ স্ট্রিং ডিকোড করুন

যেহেতু %%EXTRA_TAG_DATA%% ম্যাক্রোর মাধ্যমে পাঠানো তথ্য অবশ্যই URL-এর মাধ্যমে পাঠানো হবে, Google সার্ভারগুলি এটিকে ওয়েব-সেফ বেস64 ( RFC 3548 ) দিয়ে এনকোড করে।

তাই ডিক্রিপশনের চেষ্টা করার আগে, আপনাকে অবশ্যই ASCII অক্ষরগুলিকে একটি বাইটেস্ট্রিং-এ ডিকোড করতে হবে। নিচের নমুনা C++ কোডটি OpenSSL প্রজেক্টের BIO_f_base64() এর উপর ভিত্তি করে, এবং এটি 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 এর প্রতিটি বিভাগের জন্য, সংশ্লিষ্ট 20-বাইট ciphertext তৈরি করা হয় এইভাবে:

<byte_array <xor> HMAC(encryption_key, initialization_vector || counter_bytes)>

যেখানে || সংমিশ্রণ হয়।

সংজ্ঞা

পরিবর্তনশীল বিস্তারিত
initialization_vector 16 বাইট - ছাপ অনন্য।
encryption_key 32 বাইট - অ্যাকাউন্ট সেটআপে সরবরাহ করা হয়েছে।
integrity_key 32 বাইট - অ্যাকাউন্ট সেটআপে সরবরাহ করা হয়েছে।
byte_array 20-বাইট বিভাগে একটি ক্রমিকিত ExtraTagData অবজেক্ট।
counter_bytes বাইট মান বিভাগটির ক্রমিক সংখ্যা দেখাচ্ছে, নীচে দেখুন।
final_message %%EXTRA_TAG_DATA%% ম্যাক্রোর মাধ্যমে পাঠানো মোট বাইট অ্যারে (বিয়োগ WebSafeBase64 এনকোডিং)।
অপারেটর বিস্তারিত
hmac(key, data) SHA-1 HMAC, data এনক্রিপ্ট করতে key ব্যবহার করে।
a || b স্ট্রিং a স্ট্রিং b এর সাথে সংযুক্ত।

কাউন্টার_বাইট গণনা করুন

counter_bytes ciphertext প্রতিটি 20-বাইট বিভাগের ক্রম চিহ্নিত করে। মনে রাখবেন যে শেষ বিভাগে 1 থেকে 20 বাইটের মধ্যে থাকতে পারে। আপনার hmac() ফাংশন চালানোর সময় সঠিক মান দিয়ে counter_bytes পূরণ করতে, 20-বাইট বিভাগ গণনা করুন (বাকি সহ) এবং নিম্নলিখিত রেফারেন্স টেবিল ব্যবহার করুন:

বিভাগ নম্বর counter_bytes মান
0 কোনোটিই নয়
1 … 256 1 বাইট। মান ক্রমিকভাবে 0 থেকে 255 পর্যন্ত বৃদ্ধি পায়।
257 … 512 2 বাইট। প্রথম বাইটের মান 0, দ্বিতীয় বাইটের মান ক্রমিকভাবে 0 থেকে 255 পর্যন্ত বৃদ্ধি পায়।
513 … 768 3 বাইট। প্রথম দুটি বাইটের মান হল 0, শেষ বাইটের মান ক্রমিকভাবে 0 থেকে 255 পর্যন্ত বৃদ্ধি পায়।

উপরে ফিরে যাও

এনক্রিপশন স্কিম

এনক্রিপশন স্কিম হাইপারলোকাল টার্গেটিং সিগন্যাল ডিক্রিপ্ট করার জন্য ব্যবহৃত একই স্কিমের উপর ভিত্তি করে।

  1. সিরিয়ালাইজেশন : প্রোটোকল বাফারে সংজ্ঞায়িত ExtraTagData অবজেক্টের একটি উদাহরণ প্রথমে SerializeAsString() এর মাধ্যমে একটি বাইট অ্যারেতে সিরিয়াল করা হয়।

  2. এনক্রিপশন : পর্যাপ্ত নিরাপত্তা নিশ্চিত করার সময় ওভারহেডের আকার ছোট করার জন্য ডিজাইন করা একটি কাস্টম এনক্রিপশন স্কিম ব্যবহার করে বাইট অ্যারে এনক্রিপ্ট করা হয়। এনক্রিপশন স্কিমটি initialization_vector উপর ভিত্তি করে একটি গোপন প্যাড তৈরি করতে একটি কীড HMAC অ্যালগরিদম ব্যবহার করে, যা ইমপ্রেশন ইভেন্টের জন্য অনন্য।

এনক্রিপশন সিউডোকোড

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. যাচাই করুন : ইন্টিগ্রিটি সিগনেচারটি HMAC(integrity_key, byte_array || initialization_vector) এর 4 বাইট পাস করে

ডিক্রিপশন সিউডোকোড

// 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;
}

C++ প্রোটোকল বাফার ডকুমেন্টেশনে বর্ণিত ParseFromString() ব্যবহার করে আপনাকে এটিকে ডিসিরিয়ালাইজ করতে হবে।

Android advertising_id এবং iOS hashed_idfa ক্ষেত্রের বিশদ বিবরণের জন্য, IDFA এর সাথে বিজ্ঞাপন আইডি এবং টার্গেটিং মোবাইল অ্যাপ ইনভেন্টরি ডিক্রিপ্ট করুন।

জাভা লাইব্রেরি

বিজ্ঞাপন নেটওয়ার্কের জন্য বিজ্ঞাপনদাতা শনাক্তকারীকে এনকোড এবং ডিকোড করতে ক্রিপ্টো অ্যালগরিদম প্রয়োগ করার পরিবর্তে, আপনি DoubleClickCrypto.java ব্যবহার করতে পারেন। আরও তথ্যের জন্য, ক্রিপ্টোগ্রাফি দেখুন।