@anzumame

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

ExcelVBAで、bitbank APIを使って資産残高(assets)を取得したい

解決したいこと

ExcelVBAで、bitbankAPIを使って資産残高(assets)を取得しようとしています
bitbankAPI仕様書→https://github.com/bitbankinc/bitbank-api-docs/blob/master/rest-api_JP.md
しかし、API認証に失敗してしまいます
「HMAC-SHA256形式の署名作成」が正しく行われていないと考えているのですが、解決できず、
原因がわかりましたらどうかご教授お願いいたします。

※bitFlyerAPIでも同様の実装を行い、こちらは正しく動作しました。

発生している問題・エラー

{"success":0,"data":{"code":20001}} ※20001 API認証に失敗しました

該当するソースコード

Option Explicit

' bitBank:口座残高を取得する~PrivateAPI
Public Sub bitBankAPI_Assets()

    Const API_KEY    As String = "***** API_KEY *****"
    Const API_SECRET As String = "***** SECRET_KEY *****"

    ' ▽ タイムスタンプを取得 ▽
    Dim timestamp   As String
    timestamp = DateDiff("s", "1970/1/1 9:00", Now)

    ' ▽ HMAC-SHA256形式の署名作成 ▽
    '   ※文字列(「ACCESS-NONCE、リクエストのパス」 を連結させたもの)を 
    '      HMAC-SHA256 形式でAPIシークレットキーを使って署名作成

    ' キーとテキストのバイト配列を作成
    Dim keyBytes()   As Byte
    Dim textBytes()  As Byte
    keyBytes = StrConv(API_SECRET, vbFromUnicode)
    textBytes = StrConv(timestamp & "/v1/user/assets", vbFromUnicode)

    ' バイト配列のハッシュ値を取得
    Dim hmac        As Object
    Dim hashBytes() As Byte
    Set hmac = CreateObject("System.Security.Cryptography.HMACSHA256")
    hmac.Key = keyBytes
    hashBytes = hmac.ComputeHash_2(textBytes)
    Set hmac = Nothing

    '' 文字列に変換する
    Dim hashByte    As Variant
    Dim hash        As String
    For Each hashByte In hashBytes
        hash = hash & Right("0" & Hex(hashByte), 2)
    Next

    ' ▽ API呼び出し ▽

    ' Http Open
    Dim http        As New MSXML2.XMLHTTP
    http.Open "GET", "https://api.bitbank.cc/v1/user/assets", False

    ' HTTPリクエストヘッダーに付与
    http.setRequestHeader "ACCESS-KEY", API_KEY
    http.setRequestHeader "ACCESS-NONCE", timestamp
    http.setRequestHeader "ACCESS-SIGNATURE", hash
    http.setRequestHeader "Content-Type", "application/json"

    ' リクエストを送信
    http.send Null

    ' ▽ 結果表示 ▽
    Debug.Print http.responseText
End Sub

※環境は、Windows10、Excel for Microsoft365

準備

・bitbankサイトでAPIキーを発行し、「APIキー」「シークレットキー」を取得
 (参考ページ https://support.bitbank.cc/hc/ja/articles/360036234574-API%E3%82%AD%E3%83%BC%E3%81%AE%E7%99%BA%E8%A1%8C%E3%81%A8API%E4%BB%95%E6%A7%98%E3%81%AE%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95)
・"System.Security.Cryptography.HMACSHA256" を生成するのに、Windowsに.NET Framework 3.5をインストールする
(参考ページ http://footprintsofashcolorsparrow.blogspot.com/2017/10/windowsexcel-vbanet-framework.html)
・VBA参照設定:「Microsoft XML,v3.0」を追加

確認した事

・APIキーの再発行をしてみましたが、ダメでした。
・「APIキー」「シークレットキー」は間違いありません
 (「CryptoLinC」のAPI連携で正しく連携することができました)

0 likes

2Answer

公式の Node.js 用 SDK と見比べてみましたが特におかしいところはなさそうですね。https://github.com/bitbankinc/node-bitbankcc/blob/master/src/lib/private-api.ts

細かい点ですが、公式 SDK だと HMAC ハッシュの hex 文字列は小文字のようです。 hash = hash & Right("0" & Hex(hashByte), 2) だと hex 文字列が大文字になります。この違いに意味があるとは考えづらいですが、念のため小文字にしてみては。

1Like

Comments

  1. @anzumame

    Questioner

    早速のご回答ありがとうございました。
    はい。小文字に変換して試してみましたが、結果は同じく認証に失敗してしまいました。
  2. 手元に Excel がないため突っ込んだ回答ができず申し訳ないです。

    仕様書に curl でリクエストする例が載っていたので、これを実行して正しくリクエストできるか、また VBA の実装で同じシグネチャが生成できているか確かめるといいかもしれません(curl と openssl がインストールされている必要があります)。

    export API_KEY=___your api key___
    export API_SECRET=___your api secret___
    export ACCESS_NONCE="$(date +%s)"
    export ACCESS_SIGNATURE="$(echo -n "$ACCESS_NONCE/v1/user/assets" | openssl dgst -sha256 -hmac "$API_SECRET")"

    curl -H 'ACCESS-KEY:'"$API_KEY"'' -H 'ACCESS-NONCE:'"$ACCESS_NONCE"'' -H 'ACCESS-SIGNATURE:'"$ACCESS_SIGNATURE"'' https://api.bitbank.cc/v1/user/assets
  3. @anzumame

    Questioner

    回答ありがとうございました。
    はい。VBA以外の視点の確認も進めてみます。
    また、結果などをコメントさせていただきます。

自己解決できましたので、結果を挙げておきます。

##【原因】
リクエストに「クエリパラメータ」が指定されていない

##【対応】
「クエリパラメータ」=***"None"***を指定したところ正しく動作しました。
下記ソース部分を修正しました。
(修正前)

http.Open "GET", "https://api.bitbank.cc/v1/user/assets", False

(修正後)

http.Open "GET", "https://api.bitbank.cc/v1/user/assets?None", False

##【メモ】
※仕様書にはassetsの説明に「Parameters: None」となっていたため、パラメータ無しと解釈してたのですが、実際は"None"のパラメータを設定すると言うことなのか?(サンプルにも記載されていませんでした)
※これが正しい原因&対応なのかは不明です。あくまでも結果論です。

0Like

Your answer might help someone💌