解密价格确认
在您的广告素材赢得竞价后,如果定义该广告素材的 HTML 代码段包含 WINNING_PRICE 宏,Google 可以将胜出价格通知给您。Google 会以加密格式返回胜出价格。下列主题将介绍您的应用如何解密胜出价格信息。
情形
依赖关系
示例代码
加密机制
解密机制
检测过期响应***
情形
您的应用在返回给 Google 的 HTML 代码段中加入 WINNING_PRICE 宏。
Google 以未填补的网络安全 base64 编码形式 (RFC 3548),使用胜出价格替换该宏。
代码段以您选择的任意格式传递确认信息,例如将其放入作为广告内容显示的隐藏像素请求的网址中。
在服务器上,您的应用将胜出价格信息转换为 base64 编码,然后解密结果。
依赖关系
您需要支持 SHA-1 HMAC 的 Crypto 库,例如 Openssl。
示例代码
我们提供 Java 和 C++ 的示例代码,您可以访问 http://code.google.com/p/privatedatacommunicationprotocol 下载这些示例。
Java 示例代码使用 Apache Commons 项目的 base64 ×××。您不需要下载 Apache Commons 代码,因为参考实施已包括必要的代码,可以自行运作。
C++ 示例代码使用 OpenSSL base64 BIO 方法。该方法会获取以网络安全 base64 编码的字符串 (RFC 3548),并对其进行解码。网络安全 base64 字符串通常会使用“.”来替换“=”(请注意,在此加入引号是为了阅读方便,引号并不是协议的一部分);不过,这样替换宏时并不会填补已加密的价格。由于 OpenSSL 无法处理未填补的字符串,因此参考实施会添加填补内容。
加密机制
Google 使用自定义的加密机制对价格进行加密,其设计可尽量缩减加密文件的大小,同时保证所需的安全性。这项加密机制使用密钥验证 HMAC 算法,可根据唯一展示活动 ID 来生成秘密的填补内容。
加密价格的长度固定为 28 个字节,其中包含 16 个字节的初始化矢量、8 个字节的密文以及 4 个字节的完整性签名。加密的价格根据 RFC 3548 使用网络安全 base64 方式编码,会省略填补的字符。因此,28 个字节的加密价格会被编成 38 个字符的网络安全 base-64 字符串。
加密格式如下:
{initialization_vector (16 bytes)}{encrypted_price (8 bytes)}
{integrity (4 bytes)}
价格会被加密成 <price xor HMAC(encryption_key, initialization_vector)> 的格式,解密时系统会计算加密价格的 HMAC(encryption_key,initialization_vector) 和 xor 以恢复到加密前的结果。完整性阶段会使用 4 个字节的 <HMAC(integrity_key, price||initialization_vector)>,其中 || 表示“并列”的意思。
输入内容
iv 初始化矢量(16 个字节 - 展示专用值)
e_key 加密密钥(32 个字节 - 在创建帐户时提供)
i_key 完整性密钥(32 个字节 - 在创建帐户时提供)
price (8 个字节 - 以帐户币种的百万分之一表示)
表示法
hmac(k, d) 数据 d 的 SHA-1 HMAC,使用密钥 k。
a || b 字符串 a 和字符串 b 并列
伪代码
pad = hmac(e_key, iv) // 前 8 个字节
enc_price = pad <xor> price
signature = hmac(i_key, price || iv) // 前 4 个字节
final_message = WebSafeBase64Encode( iv || enc_price || signature )
解密机制
您的解密代码必须使用加密密钥对价格进行解密,并使用完整性密钥验证完整性位元。您在设置时就会获得密钥。至于如何组织实施,则完全由您决定。您应该可以直接引用绝大多数示例代码,然后再根据需要进行修改。
输入内容
e_key 加密密钥,32 个字节 - 在创建帐户时提供
i_key 完整性密钥,32 个字节 - 在创建帐户时提供
final_message 使用网络安全 base64 编码的 38 个字符
伪代码
enc_price = WebSafeBase64Decode(final_message)
(iv, p, sig) = dec_price -- split up according to fixed lengths
price_pad = hmac(e_key, iv)
price = p <xor> price_pad
conf_sig = hmac(i_key, price || iv)
success = (conf_sig == sig)
检测过期响应***
要检测过期响应***或重现这些***,建议您使用时间戳对响应进行过滤。在排除了因时区导致的差异后,选出和系统时间明显有差别的响应即可。
初始化矢量的前 8 个字节包含时间戳,您可以使用下列 C++ 函数对其进行读取:
void GetTime(const char* iv, struct timeval* tv) {
uint32 val;
memcpy(&val, iv, sizeof(val));
tv->tv_sec = htonl(val);
memcpy(&val, iv+sizeof(val), sizeof(val));
tv->tv_usec = htonl(val)
}
您可以使用下列 C++ 代码,将上述时间戳转换为用户可读的内容:
struct tm tm;
localtime_r(&tv->tv_sec, &tm);
printf("%04d-%02d-%02d|%02d:%02d:%02d.%06ld",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec,
tv_.tv_usec);
来源:https://developers.google.com/ad-exchange/rtb/response-guide/decrypt-price?hl=zh-cn
转载于:https://blog.51cto.com/hehe1987/1649670