Coinbase Exchange API与PowerShell

时间:2015-03-01 23:09:41

标签: powershell coinbase-api

我觉得我非常接近能够在PowerShell中使用Coinbase Exchange API,但我在创建有效签名方面遇到了麻烦。不需要签名的请求,例如/时间和/产品,效果很好。

这是我到目前为止所拥有的。

$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

1 个答案:

答案 0 :(得分:3)

在审核了一些C# code in the Coinbase community后,我能够修改我的代码并使其正常运行。解密密钥不需要转换为字符串格式,这是在将秘密传递给HMAC函数之前调用Base64-Decode时发生的情况。我按照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