使用 HTTP_X_SIGNATURE 验证 Coinbase IPN
Posted
技术标签:
【中文标题】使用 HTTP_X_SIGNATURE 验证 Coinbase IPN【英文标题】:Verify Coinbase IPNs using HTTP_X_SIGNATURE 【发布时间】:2015-04-13 05:18:20 【问题描述】:我已经为比特币交易集成了 Coinbase,除了已经实现的其他安全功能之外,我还想使用他们的签名来验证 IPN 是否真的来自他们。
他们的支持表明“验证 x_signature 标头中包含正确的签名。包含的签名将使用以下公钥完成:https://www.coinbase.com/coinbase.pub。”
使用openssl_verify documentation,我整理了以下内容:
function verifyX_SIGNATURE()
// $data and $signature are assumed to contain the data and the signature
// fetch public key from certificate and ready it
$fp = fopen("https://www.coinbase.com/coinbase.pub", "r");
$cert = fread($fp, 8192);
fclose($fp);
$pubkeyid = openssl_pkey_get_public($cert);
// from $_SERVER['HTTP_X_SIGNATURE'] header (data masked)
$signature = 'G8hpTMmWpwoW+6y6lNTbM5hCpHc9kJJcZ7Oij6I94UiwZeeS8zymuqhv+YE2tmXHCR6MqO+KU1HUrbo5simYfSaGjsRWtT0oQYhLI0qKqko3kxiVZ37B6gmflTfcJiiS0vWuUgOeEMIFL8CNPVFI+snr50c7CZdDl36Tg0Neu0XbxpVqfDBI5WVzQT3ujo6aR/CYnIbcWJ06Klfpd+EFTtzfKU0viMlqh7dWdZEnXg+u9Z3QMyfPGDd/G+QJzNTej7/L18OYo7TzfRHG+HAxxrURS8/616LNF6qvx3mMWtrHE77Hvw+DNhtjy0bzm58pencX5iuGDKo7hbP6fbqFqYgX3ZYokn/EhuqtUto8kI8WMqCV+wdLcVa5fasswAr58l9LuxnTrkCEB/uWAukDbL+qkkBLZabUTUrG2qJUk0ZHJura3XcfwTtCkanJ49ZaKsk0WaosAeWnrDxTBSwXhFGeFMGvK1u+5ffQlyG2Ndd7gtHPVQGpbMJr2FKyGYIuXDckOlQh6vG85PrE8OSMSY+/LozYyKXYiPaA75ZCpCCXuHgQ+pdxoB2QwM6zx+v8n8doW5OLudlP654GmDLG+wVwbdIQNQlU00ZD/ndAUTwa9pMJjRyL3uHIgAom7vXFfQPYlIvZ/unT5l1uHmmKbkLGkMh/IP5ZJauyfuBIUcg=';
// IPN sent in JSON (data masked)
$data = '"order":"id":"BWU44QUL","created_at":"2015-02-11T14:49:41-08:00","status":"completed","event":"type":"completed","total_btc":"cents":345660.0,"currency_iso":"BTC","total_native":"cents":30.0,"currency_iso":"USD","total_payout":"cents":0.0,"currency_iso":"USD","custom":"1089215012665154939","receive_address":"QRwGZSkh3eoj4XTJFk1rZsy74zTouHY5HA","button":"type":"buy_now","subscription":false,"repeat":null,"name":"30 karma","description":"30 karma @ $0.01 USD each","id":"9bd1d424582687qac22c3037u5axacf1","refund_address":"1Fn2ou3rZRStYgtq8v6Taz47drueyQzrF2","transaction":"id":"54b8441c7dsfbb9b38105022","hash":"ad9d5d6671b6764fc122923fff90a5b7cdb5ec531eb42cd92bda937465b98d76","confirmations":0';
// state whether signature is okay or not
$ok = openssl_verify($data, $signature, $pubkeyid);
if ($ok == 1)
echo "good";
elseif ($ok == 0)
echo "bad";
else
echo "ugly, error checking signature";
// free the key from memory
openssl_free_key($pubkeyid);
这不是验证(即打印“坏”)并且他们的 API 库没有功能。我已经掩盖了数据,但如果我在这个过程中做错了什么,我将不胜感激。提前谢谢你。
【问题讨论】:
您是否尝试将字节数减少到 2048?您还应该使用相同的运算符 ===。并检查 -1 将字节更改为 2048 并没有什么不同。仍然打印不好。 【参考方案1】:openssl_verify 适用于原始二进制字符串,而不是其 base64 表示。在将base64_decode
传递给openssl_verify
之前,只需将base64_decode
传递给$signature
,就可以了。
除此之外,第三个参数接受常规 PEM 字符串键,因此只需将其直接传递给方法即可。
【讨论】:
@valME.io 已编辑答案以上是关于使用 HTTP_X_SIGNATURE 验证 Coinbase IPN的主要内容,如果未能解决你的问题,请参考以下文章