Karakuri.com

Fintechではたらくアプリケーションエンジニアの技術録

C#でcoincheckのPrivate APIを利用するための認証SIGNATUREの作り方

株やFXはAPIが用意されていないのですが、仮想通貨取引所はどこもAPIを用意しています。coincheckも例外ではなくAPIを利用してBitcoinのレバレッジ取引ができます。つまりは自分でシステムトレードプログラムを作ることができるというわけですね。個人の口座残高や売買などはPrivate APIという認証が必要なAPIを使用する必要があります。今回はこの認証をC#で実装する方法について書き残します。

coincheckの認証とは

細かいことはcoincheckのAPI仕様についてのページに書いてあるので参照してください。
coincheck.com
簡単にいうと下記の3つの情報をHTTPsのヘッダに書き込めば良いみたいですね。

  • ACCESS KEY
  • ACCESS NONCE
  • ACCESS SIGNATURE

KEYはcoincheckにログインして作成することができます。権限も細かく設定できるので、必要最低限の権限だけ付与しましょう。特に送金は余程のことがない限り権限付与しないほうが良いです。NONCEは前回のAPIの実行時より大きい値であれば何でも良いです。そしてSIGNATURE、今回はこの作り方について書きます。

SIGNATUREとは

SIGNATUREは、ACCESS-NONCE, リクエスト先URL, リクエストのボディ を全て文字列にし連結したものを、HMAC-SHA256 hash形式でシークレットキーを使って署名した結果です。

つまりはデジタル署名ですね。JSONデータを途中で改ざんされても検知できるように求めているのでしょう。

SIGNATUREの作り方

private string ComputeHash(string body)
{
   var secret = secretAccessKey;
   var message = nonce + uri + body;

   using (var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret)))
   {
       var bs = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(message));
       return BitConverter.ToString(bs).ToLower().Replace("-", "");
   }
}

.Net FrameworkのHMACSHA256クラスを使えばOKです。ただ、そのまま使ってしまうとcoincheckが求めるハッシュ値のフォーマットと合わないみたいなので、全部小文字に変換したりハイフンを消したりしています。ここら辺のフォーマットはcoincheckに説明はないのですが、javaなどのサンプルコードを参考に割り出してみた結果C#ではこうなりました。
ちなみにリクエストのボディですが、これはC#だとDataContractクラスをシリアライズして作成したJSONのStringをそのまま使えばOKです。

public string CreateJsonBody(object obj)
{
    using (var stream = new MemoryStream())
    {
        serializer = new DataContractJsonSerializer(obj.GetType());
        serializer.WriteObject(stream, obj);
        stream.Position = 0;

        using (var streamReader = new StreamReader(stream))
        {
            return streamReader.ReadToEnd();
        }
    }
}

[DataContract]
class Response
{
    [DataMember(Name = "last")]
    public double Last { get; set; }
}

動作確認の方法

動作確認で実取引が発生するのは怖いので、口座の残高APIで試してみれば良いと思います。これが通れば一先ず署名は合ってます。ただGETなのでJSONがないので、POSTは別のAPIで試してみないといけません。。