2015-03-01 3 views
2

Я чувствую, что я действительно близок к тому, чтобы использовать Coinbase Exchange API с PowerShell, но мне не удается создать действительную подпись. Запросы, которые не требуют подписи, например/time и/products, отлично работают.Coinbase Exchange API с PowerShell

Вот что у меня есть.

$api = @{ 
    "endpoint" = 'https://api.gdax.com' 
    "url" = '/account' 
    "method" = 'GET' 
    "body" = '' 
    "key" = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 
    "secret" = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 
    "passphrase" = 'xxxxxxxx' 
} 

# Base64 encoding/decoding functions derived from 
# http://vstepic.blogspot.com/2013/02/how-to-convert-string-to-base64-and.html 
function Base64-Encode($string) { 
    $conversion = [System.Text.Encoding]::ASCII.GetBytes($string) 
    return [System.Convert]::ToBase64String($conversion) 
} 

function Base64-Decode($string) { 
    $conversion = [System.Convert]::FromBase64String($string) 
    return [System.Text.Encoding]::ASCII.GetString($conversion) 
} 

# HMAC SHA256 code derived from 
# http://www.jokecamp.com/blog/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/ 
function hmac($message, $secret) { 
    $hmacsha = New-Object System.Security.Cryptography.HMACSHA256 
    $hmacsha.key = [Text.Encoding]::ASCII.GetBytes($secret) 
    $signature = $hmacsha.ComputeHash([Text.Encoding]::ASCII.GetBytes($message)) 
    $signature = [Convert]::ToBase64String($signature) 
    return $signature 
} 

function Submit-Request($request) { 
    $unixEpochStart = Get-Date -Date "01/01/1970" 
    $now = Get-Date 
    $timestamp = (New-TimeSpan -Start $unixEpochStart -End $now.ToUniversalTime()).TotalSeconds.ToString() 
    # create the prehash string by concatenating required parts 
    $prehash = $timestamp + $request.method.ToUpper() + $request.url + $request.body 
    $signature_b64 = hmac -message $prehash -secret (Base64-Decode $request.secret) 
    $header = @{ 
     "CB-ACCESS-KEY" = $request.key 
     "CB-ACCESS-SIGN" = $signature_b64 
     "CB-ACCESS-TIMESTAMP" = $timestamp 
     "CB-ACCESS-PASSPHRASE" = $request.passphrase 
     "Content-Type" = 'application/json' 
    } 
    $uri = $request.endpoint + $request.url 
    if ($request.method.ToUpper() -eq 'POST') { 
     $response = Invoke-RestMethod -Method $request.method -Uri $uri -Headers $header -Body $request.body 
    } else { 
     $response = Invoke-RestMethod -Method $request.method -Uri $uri -Headers $header 
    } 
    return $response 
} 

$api.method = 'GET' 
$api.url = '/account' 
$response = Submit-Request $api 
Write-Output $response 

ответ

3

После рассмотрения некоторых C# code in the Coinbase community, я был в состоянии пересмотреть свой код и получить его работу. Декодирование секретного ключа не нужно было переходить в строковый формат, что и происходило, когда я вызывал Base64-Decode, прежде чем передавать секрет функции HMAC. Я следовал примеру C# и декодировал его непосредственно в функции HMAC, не выбирая из него строку. Другое изменение, которое я сделал, это сделать временную метку совпадающей с форматом, полученным из/time, используя 3 десятичных знака вместо 5.

Вот мой пересмотренный код. Надеюсь, это поможет другим.

$api = @{ 
    "endpoint" = 'https://api.gdax.com' 
    "url" = '/account' 
    "method" = 'GET' 
    "body" = '' 
    "key" = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 
    "secret" = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 
    "passphrase" = 'xxxxxxxx' 
} 

# Base64 encoding/decoding functions derived from 
# http://vstepic.blogspot.com/2013/02/how-to-convert-string-to-base64-and.html 
function Base64-Encode($string) { 
    $conversion = [System.Text.Encoding]::ASCII.GetBytes($string) 
    return [System.Convert]::ToBase64String($conversion) 
} 

function Base64-Decode($string) { 
    $conversion = [System.Convert]::FromBase64String($string) 
    return [System.Text.Encoding]::ASCII.GetString($conversion) 
} 

# HMAC SHA256 code derived from 
# http://www.jokecamp.com/blog/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/ 
function hmac($message, $secret) { 
    $hmacsha = New-Object System.Security.Cryptography.HMACSHA256 
    $hmacsha.key = [Convert]::FromBase64String($secret) 
    $signature = $hmacsha.ComputeHash([Text.Encoding]::ASCII.GetBytes($message)) 
    $signature = [Convert]::ToBase64String($signature) 
    return $signature 
} 

function Submit-Request($request) { 
    $unixEpochStart = Get-Date -Date "01/01/1970" 
    $now = Get-Date 
    $timestamp = (New-TimeSpan -Start $unixEpochStart -End $now.ToUniversalTime()).TotalSeconds 
    # round timestamp to 3 decimal places and convert to string 
    $timestamp = ([math]::Round($timestamp, 3)).ToString() 
    # create the prehash string by concatenating required parts 
    $prehash = $timestamp + $request.method.ToUpper() + $request.url + $request.body 
    $signature_b64 = hmac -message $prehash -secret $request.secret 
    $header = @{ 
     "CB-ACCESS-KEY" = $request.key 
     "CB-ACCESS-SIGN" = $signature_b64 
     "CB-ACCESS-TIMESTAMP" = $timestamp 
     "CB-ACCESS-PASSPHRASE" = $request.passphrase 
     "Content-Type" = 'application/json' 
    } 
    $uri = $request.endpoint + $request.url 
    if ($request.method.ToUpper() -eq 'POST') { 
     $response = Invoke-RestMethod -Method $request.method -Uri $uri -Headers $header -Body $request.body 
    } else { 
     $response = Invoke-RestMethod -Method $request.method -Uri $uri -Headers $header 
    } 
    return $response 
} 

$api.method = 'GET' 
$api.url = '/accounts' 
$response = Submit-Request $api 
Write-Output $response