Refactored common crypto/encoding functions.

This commit is contained in:
Adrian Gallagher
2015-03-06 14:03:52 +11:00
parent c6852f3436
commit 05abe9b466
10 changed files with 77 additions and 86 deletions

View File

@@ -6,10 +6,7 @@ import (
"fmt"
"log"
"encoding/json"
"encoding/hex"
"crypto/hmac"
"crypto/sha512"
"encoding/base64"
"errors"
"strings"
"strconv"
@@ -252,23 +249,20 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[
PayloadJson, err := json.Marshal(request)
if b.Verbose {
log.Printf("Request JSON: %s\n", PayloadJson)
}
if err != nil {
return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request")
}
PayloadBase64 := base64.StdEncoding.EncodeToString(PayloadJson)
hmac := hmac.New(sha512.New384, []byte(b.APISecret))
hmac.Write([]byte(PayloadBase64))
signature := hex.EncodeToString(hmac.Sum(nil))
if b.Verbose {
log.Printf("Request JSON: %s\n", PayloadJson)
}
PayloadBase64 := Base64Encode(PayloadJson)
hmac := GetHMAC(sha512.New384, []byte(PayloadBase64), []byte(b.APISecret))
req, err := http.NewRequest(method, BITFINEX_API_URL + path, strings.NewReader(""))
req.Header.Set("X-BFX-APIKEY", string(b.APIKey))
req.Header.Set("X-BFX-APIKEY", b.APIKey)
req.Header.Set("X-BFX-PAYLOAD", PayloadBase64)
req.Header.Set("X-BFX-SIGNATURE", signature)
req.Header.Set("X-BFX-SIGNATURE", HexEncodeToString(hmac))
client := &http.Client{}
resp, err := client.Do(req)

View File

@@ -5,9 +5,7 @@ import (
"net/url"
"io/ioutil"
"log"
"encoding/hex"
"encoding/json"
"crypto/hmac"
"crypto/sha256"
"strings"
"strconv"
@@ -271,9 +269,8 @@ func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, values url.Values,
nonce := strconv.FormatInt(time.Now().UnixNano(), 10)
values.Set("key", b.APIKey)
values.Set("nonce", nonce)
hmac := hmac.New(sha256.New, []byte(b.APISecret))
hmac.Write([]byte(nonce + b.ClientID + b.APIKey))
values.Set("signature", strings.ToUpper(hex.EncodeToString(hmac.Sum(nil))))
hmac := GetHMAC(sha256.New, []byte(nonce + b.ClientID + b.APIKey), []byte(b.APISecret))
values.Set("signature", strings.ToUpper(HexEncodeToString(hmac)))
reqBody := strings.NewReader(values.Encode())
path = BITSTAMP_API_URL + path

View File

@@ -4,10 +4,7 @@ import (
"net/http"
"net/url"
"strconv"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"encoding/hex"
"encoding/json"
"errors"
"strings"
@@ -167,20 +164,13 @@ func (b *BTCChina) SendAuthenticatedHTTPRequest(method string, params []string)
log.Println(encoded)
}
hmac := hmac.New(sha1.New, []byte(b.APISecret))
hmac.Write([]byte(encoded))
hash := hex.EncodeToString(hmac.Sum(nil))
hmac := GetHMAC(sha1.New, []byte(encoded), []byte(b.APISecret))
postData := make(map[string]interface{})
postData["method"] = method
postData["params"] = []string{}
postData["id"] = 1
data, err := json.Marshal(postData)
if b.Verbose {
log.Println(string(data))
}
if err != nil {
return errors.New("Unable to JSON POST data")
}
@@ -190,7 +180,6 @@ func (b *BTCChina) SendAuthenticatedHTTPRequest(method string, params []string)
}
reqBody := strings.NewReader(string(data))
b64 := base64.StdEncoding.EncodeToString([]byte(b.APIKey + ":" + hash))
req, err := http.NewRequest("POST", "https://api.btcchina.com/api_trade_v1.php", reqBody)
@@ -199,7 +188,7 @@ func (b *BTCChina) SendAuthenticatedHTTPRequest(method string, params []string)
}
req.Header.Add("Content-type", "application/json-rpc")
req.Header.Add("Authorization", "Basic " + b64)
req.Header.Add("Authorization", "Basic " + Base64Encode([]byte(b.APIKey + ":" + HexEncodeToString(hmac))))
req.Header.Add("Json-Rpc-Tonce", nonce)
client := &http.Client{}

View File

@@ -4,9 +4,7 @@ import (
"net/http"
"net/url"
"strconv"
"crypto/hmac"
"crypto/sha512"
"encoding/hex"
"errors"
"strings"
"time"
@@ -174,9 +172,8 @@ func (b *BTCE) SendAuthenticatedHTTPRequest(method string, values url.Values) (e
values.Set("nonce", nonce)
values.Set("method", method)
hmac := hmac.New(sha512.New, []byte(b.APISecret))
encoded := values.Encode()
hmac.Write([]byte(encoded))
hmac := GetHMAC(sha512.New, []byte(encoded), []byte(b.APISecret))
if b.Verbose {
log.Printf("Sending POST request to %s calling method %s with params %s\n", BTCE_API_URL, method, encoded)
@@ -190,7 +187,7 @@ func (b *BTCE) SendAuthenticatedHTTPRequest(method string, values url.Values) (e
}
req.Header.Add("Key", b.APIKey)
req.Header.Add("Sign", hex.EncodeToString(hmac.Sum(nil)))
req.Header.Add("Sign", HexEncodeToString(hmac))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
client := &http.Client{}

View File

@@ -2,14 +2,61 @@ package main
import (
"net/http"
"hash"
"crypto/md5"
"crypto/hmac"
"crypto/sha512"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"encoding/hex"
"io/ioutil"
"errors"
"math"
"log"
)
func roundFloat(x float64, prec int) float64 {
func GetMD5(input []byte) ([]byte) {
hash := md5.New()
hash.Write(input)
return hash.Sum(nil)
}
func GetSHA512(input []byte) ([]byte) {
sha := sha512.New()
sha.Write(input)
return sha.Sum(nil)
}
func GetSHA256(input []byte) ([]byte) {
sha := sha256.New()
sha.Write(input)
return sha.Sum(nil)
}
func GetHMAC(hash func() hash.Hash, input, key []byte) ([]byte) {
hmac := hmac.New(hash, []byte(key))
hmac.Write(input)
return hmac.Sum(nil)
}
func HexEncodeToString(input []byte) (string) {
return hex.EncodeToString(input)
}
func Base64Decode(input string) ([]byte, error) {
result, err := base64.StdEncoding.DecodeString(input)
if err != nil {
return nil, err
}
return result, nil
}
func Base64Encode(input []byte) (string) {
return base64.StdEncoding.EncodeToString(input)
}
func RoundFloat(x float64, prec int) float64 {
var rounder float64
pow := math.Pow(10, float64(prec))
intermed := x * pow
@@ -54,7 +101,7 @@ func SendHTTPRequest(url string, jsonDecode bool, result interface{}) (err error
}
if res.StatusCode != 200 {
log.Printf("HTTP status code: %d", res.StatusCode)
log.Printf("HTTP status code: %d\n", res.StatusCode)
return errors.New("Status code was not 200.")
}

View File

@@ -3,10 +3,8 @@ package main
import (
"net/http"
"net/url"
"crypto/md5"
"errors"
"strings"
"encoding/hex"
"io/ioutil"
"strconv"
"time"
@@ -199,15 +197,11 @@ func (h *HUOBI) SendAuthenticatedRequest(method string, v url.Values) (error) {
v.Set("access_key", h.AccessKey)
v.Set("created", strconv.FormatInt(time.Now().Unix(), 10))
v.Set("method", method)
hasher := md5.New()
hasher.Write([]byte(v.Encode() + "&secret_key=" + h.SecretKey))
signature := strings.ToUpper(hex.EncodeToString(hasher.Sum(nil)))
v.Set("sign", signature)
hash := GetMD5([]byte(v.Encode() + "&secret_key=" + h.SecretKey))
v.Set("sign", strings.ToLower(HexEncodeToString(hash)))
encoded := v.Encode()
if h.Verbose {
log.Printf("Signature: %s\n", signature)
log.Printf("Sending POST request to %s with params %s\n", HUOBI_API_URL, encoded)
}

View File

@@ -3,10 +3,7 @@ package main
import (
"net/http"
"strconv"
"crypto/hmac"
"crypto/sha512"
"encoding/base64"
"encoding/hex"
"errors"
"strings"
"time"
@@ -271,10 +268,8 @@ func (i *ItBit) SendAuthenticatedHTTPRequest(method string, path string, params
return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request")
}
hmac := hmac.New(sha512.New, []byte(i.APISecret))
hmac.Write([]byte(nonce + string(PayloadJson)))
hex := hex.EncodeToString(hmac.Sum(nil))
signature := base64.StdEncoding.EncodeToString([]byte(hex))
hmac := GetHMAC(sha512.New, []byte(nonce + string(PayloadJson)), []byte(i.APISecret))
signature := Base64Encode([]byte(HexEncodeToString(hmac)))
req, err := http.NewRequest(method, path, strings.NewReader(""))
req.Header.Add("Authorization", i.ClientKey + ":" + signature)

View File

@@ -4,11 +4,8 @@ import (
"log"
"fmt"
"strconv"
"encoding/base64"
"encoding/json"
"crypto/hmac"
"crypto/sha512"
"crypto/sha256"
"errors"
"time"
"strings"
@@ -21,7 +18,7 @@ const (
KRAKEN_API_URL = "https://api.kraken.com"
KRAKEN_API_VERSION = "0"
KRAKEN_SERVER_TIME = "Time"
KRAKEN_ASSETS = "ssets"
KRAKEN_ASSETS = "Assets"
KRAKEN_ASSET_PAIRS = "AssetPairs"
KRAKEN_TICKER = "Ticker"
KRAKEN_OHLC = "OHLC"
@@ -501,19 +498,14 @@ func (k *Kraken) CancelOrder(orderID int64) {
func (k *Kraken) SendAuthenticatedHTTPRequest(method string, values url.Values) (interface{}, error) {
path := fmt.Sprintf("/%s/private/%s", KRAKEN_API_VERSION, method)
values.Set("nonce", strconv.FormatInt(time.Now().UnixNano(), 10))
secret, err := base64.StdEncoding.DecodeString(k.APISecret)
secret, err := Base64Decode(k.APISecret)
if err != nil {
return nil, err
}
sha := sha256.New()
sha.Write([]byte(values.Get("nonce") + values.Encode()))
shasum := sha.Sum(nil)
hmac := hmac.New(sha512.New, []byte(secret))
hmac.Write(append([]byte(path), shasum...))
signature := base64.StdEncoding.EncodeToString(hmac.Sum(nil))
shasum := GetSHA256([]byte(values.Get("nonce") + values.Encode()))
signature := Base64Encode(GetHMAC(sha512.New, append([]byte(path), shasum...), secret))
if k.Verbose {
log.Printf("Sending POST request to %s, path: %s.", KRAKEN_API_URL, path)

View File

@@ -4,10 +4,7 @@ import (
"net/http"
"net/url"
"strconv"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"errors"
"strings"
"time"
@@ -177,26 +174,21 @@ func (l *LakeBTC) SendAuthenticatedHTTPRequest(method, params string) (err error
v.Set("method", method)
v.Set("params", params)
hmac := hmac.New(sha256.New, []byte(l.APISecret))
encoded := v.Encode()
hmac.Write([]byte(encoded))
hmac := GetHMAC(sha256.New, []byte(encoded), []byte(l.APISecret))
if l.Verbose {
log.Printf("Sending POST request to %s calling method %s with params %s\n", LAKEBTC_API_URL, method, encoded)
}
reqBody := strings.NewReader(encoded)
hash := hex.EncodeToString(hmac.Sum(nil))
b64 := base64.StdEncoding.EncodeToString([]byte(l.Email + ":" + hash))
req, err := http.NewRequest("POST", LAKEBTC_API_URL, reqBody)
req, err := http.NewRequest("POST", LAKEBTC_API_URL, strings.NewReader(encoded))
if err != nil {
return err
}
req.Header.Add("Json-Rpc-Tonce", nonce)
req.Header.Add("Authorization: Basic", b64)
req.Header.Add("Authorization: Basic", Base64Encode([]byte(l.Email + ":" + HexEncodeToString(hmac))))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
client := &http.Client{}

View File

@@ -3,10 +3,8 @@ package main
import (
"net/http"
"net/url"
"crypto/md5"
"errors"
"strings"
"encoding/hex"
"io/ioutil"
"strconv"
"fmt"
@@ -407,21 +405,17 @@ func (o *OKCoin) GetFuturesUserPosition4Fix(symbol, contractType string) {
}
func (o *OKCoin) SendAuthenticatedHTTPRequest(method string, v url.Values) (err error) {
hasher := md5.New()
hasher.Write([]byte(v.Encode() + "&secret_key=" + o.SecretKey))
signature := strings.ToUpper(hex.EncodeToString(hasher.Sum(nil)))
v.Set("sign", signature)
hasher := GetMD5([]byte(v.Encode() + "&secret_key=" + o.SecretKey))
v.Set("sign", strings.ToUpper(HexEncodeToString(hasher)))
encoded := v.Encode() + "&partner=" + o.PartnerID
path := o.APIUrl + method
if o.Verbose {
log.Printf("Signature: %s\n", signature)
log.Printf("Sending POST request to %s with params %s\n", path, encoded)
}
reqBody := strings.NewReader(encoded)
req, err := http.NewRequest("POST", path, reqBody)
req, err := http.NewRequest("POST", path, strings.NewReader(encoded))
if err != nil {
return err