Reklam Ağları için Reklamveren Tanımlayıcılarının Şifresini Çözme

kullanan Reklam Ağları Authorized Buyers aracılığıyla reklamları dolduracak JavaScript etiketleri hem Android hem de iOS cihazlar için reklamveren tanımlayıcılarını alır. Bilgiler %%EXTRA_TAG_DATA%% veya Yönetilen JavaScript etiketindeki %%ADVERTISING_IDENTIFIER%% makrosu Authorized Buyers tarafından. Bu bölümün geri kalanında, %%EXTRA_TAG_DATA%% ama gör Ayrıntılı bilgi için IDFA veya reklam kimliği ile yeniden pazarlama %%ADVERTISING_IDENTIFIER%% şifrelenmiş proto arabelleğinde Analog şekilde şifresi çözülebilen MobileAdvertisingId.

Zaman çizelgesi

  1. Reklam Ağı, JavaScript uygulama içi etiketlerini günceller Authorized Buyers kullanıcı arayüzünü kullanarak, %%EXTRA_TAG_DATA%% makrosuna aşağıda açıklandığı şekilde eklenir.
  2. Uygulama, yayın sırasında Google Mobile Ads SDK'sında ise reklamveren tanımlayıcısını güvenli bir şekilde iletmelidir.
  3. Uygulama, JavaScript etiketini %%EXTRA_TAG_DATA%% ile geri alır. makrosu, bu tanımlayıcıyı içeren şifrelenmiş Reklam Ağı protokol arabelleğiyle doldurulmuştur.
  4. Uygulama bu etiketi çalıştırır ve kazanan için Reklam Ağı'nı çağırır. reklam.
  5. Bu bilgileri kullanmak (para kazanmak) için Reklam Ağı'nın protokol arabelleğini içerir:
    1. Websafe dizesini tekrar WebSafeBase64 ile bir bayt dizesine dönüştürün.
    2. Aşağıda özetlenen şemayı kullanarak şifresini çözün.
    3. Protonun serisini kaldırın ve şuradan reklamveren kimliğini alın: ExtraTagData.advertising_id veya ExtraTagData.hashed_idfa.

Bağımlılıklar

  1. WebSafeBase64 kodlayıcı ile ilgili daha fazla bilgi edinin.
  2. SHA-1 HMAC'yi destekleyen Openssl gibi bir şifreleme kitaplığı.
  3. Google protokol arabellek derleyici ile karşılaştırın.

Websafe dizesinin kodunu çözme

Çünkü %%EXTRA_TAG_DATA%% makrosu üzerinden gönderilen bilgiler URL üzerinden gönderilmesi gerekir. Google sunucuları, bu verileri web güvenli base64 (RFC 3548) ile kodlamalıdır.

Denemeden önce bu nedenle, ASCII karakterlerin kodunu tekrar bir bayt dizesi. Aşağıdaki örnek C++ kodu, OpenSSL Projenin BIO_f_base64() işlevi kullanılır ve Google'ın örneğinin bir parçasıdır. şifre çözme kodu kullanabilirsiniz.

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

Şifrelenmiş bayt dizesinin yapısı

ASCII karakterlerinin kodunu tekrar bir bayt dizesine dönüştürdüğünüzde şifresini çözer. Şifrelenmiş bayt dizesi 3 bölüm içerir:

  • initialization_vector: 16 bayt.
  • ciphertext: 20 baytlık bölümlerden oluşan bir seri.
  • integrity_signature: 4 bayt.
{initialization_vector (16 bytes)}{ciphertext (20-byte sections)}{integrity_signature (4 bytes)}

ciphertext bayt dizisi birden fazla 20 baytlık değere bölünmüş bölümlerinin yanı sıra, en son bölümün 1 ve 20 bayt dahil. Orijinal çalışmanın her bir bölümü için byte_array, karşılık gelen 20 baytlık ciphertext şu şekilde oluşturulur:

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

Burada || birleştiriliyor.

Tanımlar

Değişken Ayrıntılar
initialization_vector 16 bayt: Gösterime özgüdür.
encryption_key 32 bayt - hesap kurulumu sırasında sağlanır.
integrity_key 32 bayt - hesap kurulumu sırasında sağlanır.
byte_array 20 baytlık bölümler halinde serileştirilmiş ExtraTagData nesnesi.
counter_bytes Bölümün sıra numarasını gösteren bayt değeri (aşağıya bakın).
final_message %%EXTRA_TAG_DATA%% makrosu üzerinden gönderilen toplam bayt dizisi (WebSafeBase64 kodlaması hariç).
Operatörler Ayrıntılar
hmac(key, data) SHA-1 HMAC, data şifrelemesi için key kullanılıyor.
a || b a dizesi, b dizesiyle birleştirilmiş.

Sayaç_baytlarını hesaplama

counter_bytes, ciphertext. Son bölümün 1 ve 20 bayt dahil. counter_bytes öğesini doğru değerle doldurmak için hmac() işlevinizi çalıştırırken öncelikle 20 baytlık bölümleri sayın (kalan miktar dahil) ve aşağıdaki referans tablosunu kullanın:

Bölüm numarası counter_bytes değer
0 Yok
1...256 1 bayt. Değer sırasıyla 0 ile 255 arasında artar.
257...512 2 bayt. İlk baytın değeri 0, ikinci baytın değeri sırayla 0'dan 255'e kadar artar.
513...768 3 bayt. İlk iki baytın değeri 0, yani son baytın değeri sırayla 0'dan 255'e kadar artar.

Başa dön

Şifreleme şeması

Şifreleme şeması, verilerin şifresini çözmekte kullanılan yerel mesafe hedefleme sinyalidir.

  1. Serialization: ExtraTagData nesnesinin Protokol arabelleğinde tanımlanan ilk olarak SerializeAsString() değerini bir bayt dizisine dönüştürür.

  2. Şifreleme: Bayt dizisi daha sonra bir boyut ek yükünü en aza indirecek şekilde tasarlanmış özel şifreleme şeması müzakere tekniklerini konuşacağız. Şifreleme şeması, anahtar değer içeren bir HMAC algoritması kullanır. benzersiz bir gizli klavye alanı (initialization_vector) temel alınarak gösterim etkinliğidir.

Şifreleme sözde kodu

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

Şifre çözme şeması

Şifre çözme kodunuz 1) şifrelemeyi kullanarak protokol arabelleğinin şifresini çözmelidir anahtarı ile 2) bütünlük bitlerini bütünlük anahtarıyla doğrulama Anahtarlar sağlayacağız. Kuralların uygulanmasına ilişkin ve yapın. Çoğunlukla, projeyle ilgili ve ihtiyaçlarınıza göre uyarlayın.

  1. Panonuzu oluşturun: HMAC(encryption_key, initialization_vector || counter_bytes)
  2. ÖZELVEYA: Bu sonucu ve <xor> şifrelemeyi tersine çevirmek için şifrelenmiş metin.
  3. Doğrula: Bütünlük imzası 4 baytlık HMAC(integrity_key, byte_array || initialization_vector)

Şifre çözme sözde kodu

// 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)

Örnek C++ kodu

Aşağıda, şifre çözme daha fazla bilgi edinin.

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');
    }
  }

Reklam Ağı protokol arabelleğinden veri al

Veri ana makinesinde iletilen verilerin kodunu çözüp bunların şifresini çözdüğünüzde %%EXTRA_TAG_DATA%%, protokol arabelleğinin serisini devre dışı bırakmaya hazırsınız ve hedefleme için reklamveren tanımlayıcısını alın.

Protokol arabellekleri hakkında bilginiz yoksa belgelerimizle başlayın.

Tanım

Reklam Ağı protokol tamponu şu şekilde tanımlanır:

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

Şu sayfada açıklandığı gibi ParseFromString() kullanarak dizini seri durumdan çıkarmanız gerekir: C++ protokol arabelleği dokümanları.

Android advertising_id ve iOS ile ilgili ayrıntılar için hashed_idfa alanları, Şifre Çözme bölümüne bakın Reklam kimliği ve Mobil uygulamayı hedefleme IDFA'lı envanter var.

Java kitaplığı

Kodlamak ve kodunu çözmek için kripto algoritmalarını uygulamak yerine reklam ağları için Reklamveren Tanımlayıcıları'nı kullanabilirsiniz. DoubleClickCrypto.java. Daha fazla bilgi için bkz. Kriptografi.