プライベートAPIを操作する場合にはHMACというメッセージ認証コードを使うのが主流です。その中でも最近、特によく使われるのが「HMAC-SHA256」や「HMAC-SHA512」を使った署名です。
実際にプライベートAPIを操作する際には、HMACを使ったコードを書く必要がありますので、最低限の技術を覚えておきましょう。当然、このサイトで何回も紹介しているPythonで操作が可能なので、サンプルコードもご紹介します。
暗号化について専門的に勉強したい訳ではない場合は、「ふーん」という程度で良いのですが、どの様な技術を使っているのかは何となく覚えておきましょう^^
■今回の内容の前提知識(不明な部分があればキャッチアップして下さい)
・Pythonの基本文法が分かる
・暗号化に関する基本が分かる ※本当に基本でOKです。
・API操作の基本が分かる
コンテンツ
送信データの署名
秘匿データなどの重要な文字列を送信する際は暗号化を行います。万が一送信中のデータが漏えいしたとしてもリスクを回避できるからです。
仮想通貨関連の情報の暗号化としてよく使われているのが、メッセージ認証コードの「HMAC」という署名技術です。
HMACとは?
正式名称は「Keyed-Hashing for Message Authentication code」。
HMACでは「秘密鍵」と「暗号化のハッシュ関数」を使って計算を行っています。鍵付きのハッシングなどとも呼ばれます。
このサイトでも取り上げている仮想通貨取引所のプライベートAPIを操作する場合には、まず、APIキーとSecret(秘密鍵)を生成します。
そして、実際にAPIに送るパラメータとSecretとを併せてハッシュ値を算出し、このハッシュ値をAPIに送るという手順を踏まなければなりません。
送信するのはハッシュ値なので、万が一送信データが漏えいしたとしても、Secretを読む事はできません。これによって、実データの漏えいリスクを防止しています。
秘密鍵とは?
元々、秘密鍵は公開鍵とセットで覚えた方が良いです。これは情報処理の国家試験でしつこいくらい出てきます。。。
データを送信する際に秘密鍵を使用して暗号化した場合、送信先の相手が公開鍵を使って復号します。
逆に、公開鍵を使って暗号化した場合は、送信先の相手は秘密鍵で復号します。
公開鍵暗号方式では、鍵を1対1で作る訳ではないので、暗号化を行う際の鍵の管理が容易になります。秘密鍵は取引所でAPIキーを生成すれば大抵同時に生成されます。大切に保管しておきましょう。
暗号化ハッシュ関数とは?
暗号化を行うためのハッシュ関数は、データが正しい事を証明するためのハッシュ値(データのインデックスの様なもの)を生成して、それをデータ付与します。
データを受け取った相手は、復号を行い、データの正当性を確認します。
HMACを使ってみよう!
実際にHMACを使ってみましょう。細かい部分は仕様書を参考にして下さいね。
ちなみに仮想通貨取引所のZaifなどでもHMACを使用したAPIのリクエストコードなどが紹介されています。実際の活用方法として参考になります。
HMAC方式で暗号化を行うサンプルコード
では実際にHMAC方式で暗号化をしてみましょう。
■Pythonコード
1 2 3 4 5 6 7 8 9 10 |
import hashlib import hmac Secret = "secret word" Text_Data = "Hello!!This is Text Data!" signature = hmac.new(bytes(Secret, 'UTF-8'), bytes(Text_Data, 'UTF-8'), digestmod=hashlib.sha256) print(signature.digest()) print(signature.hexdigest()) |
■実行結果
1 2 |
b'T\x1e\x08#\xe0\x0fKy\xf4\xe6I\x1e\x82\x99\xad\x9d\x0c\r\xa1\xa3|\xe16\xd0\x03\xbc\xb2sU\xd7z~' 541e0823e00f4b79f4e6491e8299ad9d0c0da1a37ce136d003bcb27355d77a7e |
なんだか分からない文字列が出力されましたが、とりあえず暗号化されている事は分かります。1行目(b”)で囲まれた部分がdigest値、2行目が16進数のdigest値となります。16進の値を使うのが一般的です。
■コードの解説(分かる範囲で)
1)まず先頭ではhashlibとhmacのインポート
HMACを使う場合は、最初にライブラリのインポートを行いましょう。これをインポートしないとHMACもハッシュ関数も使えません。
2)次に、鍵(Secret)とmsg(Text_Data)の設定
3)hmac関数で、hmacのオブジェクトを生成。
hmacの引数は(key, msg, digestmod)となります。
keyやmsgを設定する際は基本的にbyteで渡す必要があるので、bytes関数(もしくはbytearray関数)を使って渡せばOKです。
digestmodではハッシュのアルゴリズムを指定できます。ここではAPIなどでよく使われるSHA-256を指定しています。
4)digestやhexdigestでmsgのダイジェスト値(ハッシュ値)を出力
digestでmsgのダイジェスト値を出力しています。hexdigestは文字通り16進数でダイジェスト値を出力します。このダイジェスト値をAPIに送信する訳です。
hmac.updateも覚えよう!
hmac.newでオブジェクトを作ると同時に、msgデータを作成する例を取り上げましたが、実際はhmac.updateがよく使われます。ZaifのAPI仕様などを確認してもらうと、updateを使っているのが分かるかと思います。
updateは引数をmsgに追加するという役割があります。APIに送信するデータ項目は複数存在するため、hmac.upadteでパラメータとして追加する事が多いのです。
例を見た方が分かりやすいと思いますので、コードを紹介します。
■Pythonコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import hashlib import hmac Secret = "secret word" Text_Data = "Hello!!This is Text Data!" signature = hmac.new(bytes(Secret, 'UTF-8'), bytes(Text_Data, 'UTF-8'),digestmod=hashlib.sha256) print(signature.hexdigest()) Text_Data1 = "Hello!!" Text_Data2 = "This is Text Data!" signature = hmac.new(bytes(Secret, 'UTF-8'), bytes(Text_Data1, 'UTF-8'),digestmod=hashlib.sha256) signature.update(bytes(Text_Data2, 'UTF-8')) print(signature.hexdigest()) |
■実行結果
1 2 |
541e0823e00f4b79f4e6491e8299ad9d0c0da1a37ce136d003bcb27355d77a7e 541e0823e00f4b79f4e6491e8299ad9d0c0da1a37ce136d003bcb27355d77a7e |
2つのprint分の結果が同じになりましたね。newでまとめてmsgを作った場合と比較すると、updateを使ってmsgの内容を連結できている事が分かると思います。
どの様にHMACが活用されるのかを知る
実際にHMACが使用される場合というのは、やはりAPIへリスエストするケースが多いのではないでしょうか。
多くのAPIの場合は、APIで実行したい内容(パラメータ)と、秘密鍵をセットにしてハッシュ値を計算し、そのハッシュ値を送信する事が多いです。
単なるHMACの使い方だけではなく、どの様な時にどの様に活用されるのかをしっかりと把握しておきましょう。