を使用している広告ネットワーク
認定バイヤーを通じて広告を配信する JavaScript タグでは、
Android デバイスと iOS デバイスの両方で広告主 ID を受信できる。
この情報は %%EXTRA_TAG_DATA%%
または
管理対象の JavaScript タグ内の %%ADVERTISING_IDENTIFIER%%
マクロ
認定バイヤーが対象になりますこのセクションの残りの部分では、
%%EXTRA_TAG_DATA%%
、ただし次の動画
<ph type="x-smartling-placeholder"></ph>
IDFA または広告 ID によるリマーケティングをご覧ください。
%%ADVERTISING_IDENTIFIER%%
で暗号化された proto バッファ
同様に復号できる MobileAdvertisingId
。
タイムライン
- 広告ネットワークが JavaScript アプリ内タグを更新する
認定バイヤーの管理画面を使用する
以下で説明するように
%%EXTRA_TAG_DATA%%
マクロに追加します。 - 配信時に、アプリから認定バイヤーに広告がリクエストされます。 Google Mobile Ads SDK を使用します。 広告主 ID を安全に渡せます。
- アプリが
%%EXTRA_TAG_DATA%%
を含む JavaScript タグを受け取る マクロが、その識別子を含む暗号化された広告ネットワーク プロトコル バッファで入力されます。 - アプリがこのタグを実行し、落札した広告ネットワークに対して呼び出しを行います。 表示されます。
- この情報を使用(収益化)するには、広告ネットワークで
次のように指定します。
<ph type="x-smartling-placeholder">
- </ph>
- WebSafeBase64 を使用して、ウェブセーフ文字列をバイト文字列にデコードします。
- 以下のスキームに従って復号します。
- このプロトコルを逆シリアル化し、次から広告主 ID を取得します。 ExtraTagData.advertising_id または ExtraTagData.hashed_idfa です。
依存関係
- WebSafeBase64 Encoder
- SHA-1 HMAC をサポートする暗号ライブラリ(Openssl など)。
- Google プロトコル バッファ コンパイラ。
ウェブセーフ文字列をデコードする
%%EXTRA_TAG_DATA%%
マクロを介して送信される情報は、
Google のサーバーは、ウェブセーフな base64(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<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
: 対応する 20 バイトの 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 |
文字列 b と連結された文字列 a 。 |
count_bytes を計算する
counter_bytes
は、
ciphertext
。最後のセクションには 1 ~ 1
20 バイト(両端を含む)counter_bytes
に正しい値を入力する
hmac()
関数を実行するときに、20 バイトのセクションをカウントします。
次の参照表を使用してください。
セクション番号 | counter_bytes 値 |
---|---|
撮影していない | なし |
1 ... 256 | 1 バイト。値は 0 から 255 まで順番に増加します。 |
257 ... 512 | 2 バイト。最初のバイトの値は 0、つまり 2 番目のバイトの値は 0 から 255 まで順番に増加します。 |
513 ... 768 | 3 バイト。最初の 2 バイトの値は 0、つまり最後のバイトの値は 0 から 255 まで順番に増加します。 |
暗号化スキーム
この暗号化方式は、復号鍵を復号する場合に ハイパーローカル ターゲティング シグナルを使用します。
シリアル化: ExtraTagData オブジェクトのインスタンス。 変数はまず、プロトコル バッファ内でシリアライズされ、
SerializeAsString()
をバイト配列に変換します。暗号化: 次に、バイト配列は、 サイズ オーバーヘッドを最小限に抑えながら 保護します。この暗号化スキームでは、鍵付き HMAC アルゴリズムを使用して、
initialization_vector
に基づくシークレット パッド。これは、 関連付けられます
暗号化疑似コード
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%%
: プロトコル バッファをシリアル化解除する準備ができました
ターゲティング用の広告主 ID も取得します
プロトコル バッファに馴染みがない場合は、まずドキュメントをご覧ください。
定義
Google の広告ネットワーク プロトコル バッファは次のように定義されます。
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()
を使用してシリアル化解除する必要があります。詳細については、
C++ プロトコル バッファのドキュメント。
Android advertising_id
と iOS の詳細
hashed_idfa
フィールドについては、復号
広告 ID とモバイルアプリのターゲティング
IDFA 利用が可能な広告枠
Java ライブラリ
エンコード / デコードに暗号アルゴリズムを実装する代わりに、 広告主 ID を使用する場合は、 <ph type="x-smartling-placeholder"></ph> DoubleClickCrypto.java.詳細については、次をご覧ください: 暗号化。