Skip to content

Instantly share code, notes, and snippets.

@mwerner
Last active July 18, 2018 12:13
Show Gist options
  • Save mwerner/635acb12cbc9b5569d5d to your computer and use it in GitHub Desktop.
Save mwerner/635acb12cbc9b5569d5d to your computer and use it in GitHub Desktop.
Invalid Bittrex Signature
require 'faraday'
require 'base64'
require 'cgi'
host = 'https://bittrex.com/api/v1.1'
key = '5231569363514ee5a5a598efb483c25c'
secret = '54e4a7e2a34f4d3bb9a93f765e47cf69'
path = '/account/getorderhistory'
nonce = Time.now.to_i
url = "#{host}#{path}?apikey=#{key}&nonce=#{nonce}"
connection = Faraday.new(:url => host) do |faraday|
faraday.request :url_encoded
faraday.adapter Faraday.default_adapter
end
puts "\n1: full url+queryparams, with specified params, url/secret in signature"
response = connection.get do |req|
puts "URL: #{url}"
req.url(url)
req.params[:apikey] = key
req.params[:nonce] = nonce
puts req.params.inspect
digest = OpenSSL::HMAC.hexdigest('sha512', url, secret)
signature = CGI.escape(Base64.encode64("#{digest}\n")).chomp
puts "Signed: #{signature}"
req.headers[:apisign] = signature
end
puts response.body
puts
puts "\n2: path, specified params, full url/secret in signature"
response = connection.get do |req|
puts "URL: #{path}"
req.url(path)
req.params[:apikey] = key
req.params[:nonce] = nonce
puts req.params.inspect
digest = OpenSSL::HMAC.hexdigest('sha512', url, secret)
signature = CGI.escape(Base64.encode64("#{digest}\n")).chomp
puts "Signed: #{signature}"
req.headers[:apisign] = signature
end
puts response.status
puts "\n3: path, specified params, path/secret in signature"
response = connection.get do |req|
puts "URL: #{path}"
req.url(path)
req.params[:apikey] = key
req.params[:nonce] = nonce
puts req.params.inspect
digest = OpenSSL::HMAC.hexdigest('sha512', path, secret)
signature = CGI.escape(Base64.encode64("#{digest}\n")).chomp
puts "Signed: #{signature}"
req.headers[:apisign] = signature
end
puts response.status
puts "\n4: full url requested, with no params specified, path/secret in signature"
response = connection.get do |req|
puts "URL: #{url}"
req.url(url)
puts req.params.inspect
digest = OpenSSL::HMAC.hexdigest('sha512', path, secret)
signature = CGI.escape(Base64.encode64("#{digest}\n")).chomp
puts "Signed: #{signature}"
req.headers[:apisign] = signature
end
puts response.body
puts "\n5: url with no params, params specified, host/path/secret in signature"
response = connection.get do |req|
puts "URL: #{host}/#{path}"
req.url("#{host}/#{path}")
req.params[:apikey] = key
req.params[:nonce] = nonce
puts req.params.inspect
digest = OpenSSL::HMAC.hexdigest('sha512', "#{host}/#{path}", secret)
signature = CGI.escape(Base64.encode64("#{digest}\n")).chomp
puts "Signed: #{signature}"
req.headers[:apisign] = signature
end
puts response.body
puts "\n6: url with no params, params specified, url/secret in signature"
response = connection.get do |req|
puts "URL: #{host}/#{path}"
req.url("#{host}/#{path}")
req.params[:apikey] = key
req.params[:nonce] = nonce
puts req.params.inspect
digest = OpenSSL::HMAC.hexdigest('sha512', url, secret)
signature = CGI.escape(Base64.encode64("#{digest}\n")).chomp
puts "Signed: #{signature}"
req.headers[:apisign] = signature
end
puts response.body
# Results
# $> ruby ~/Desktop/bittrex.rb
# 1: full url+queryparams, with specified params, url/secret in signature
# URL: https://bittrex.com/api/v1.1/account/getorderhistory?apikey=5231569363514ee....98efb483c25c&nonce=1403655423
# {"apikey"=>"5231569363514ee....98efb483c25c", "nonce"=>1403655423}
# Signed: MDMzMjI1M2RkNjY3NTA4YjU0ZjUwMjIwM2MxYzkxYWNhYzQxZGRhMTE0Yzdh%0AOGFkMThlOTYyZTBjNmVmZWE1ZTFiMWQ2MGRkMGZmZmVhMzRjNjc3N2NhNDNl%0AZjE3YjljYzczODRjYTljOGI3MTM3ODc2OWU5ODdjZTkyNWYzZmYK%0A
# {"success":false,"message":"INVALID_SIGNATURE","result":null}
# 2: path, specified params, full url/secret in signature
# URL: /account/getorderhistory
# {"apikey"=>"5231569363514ee....98efb483c25c", "nonce"=>1403655423}
# Signed: MDMzMjI1M2RkNjY3NTA4YjU0ZjUwMjIwM2MxYzkxYWNhYzQxZGRhMTE0Yzdh%0AOGFkMThlOTYyZTBjNmVmZWE1ZTFiMWQ2MGRkMGZmZmVhMzRjNjc3N2NhNDNl%0AZjE3YjljYzczODRjYTljOGI3MTM3ODc2OWU5ODdjZTkyNWYzZmYK%0A
# 404
# 3: path, specified params, path/secret in signature
# URL: /account/getorderhistory
# {"apikey"=>"5231569363514ee....98efb483c25c", "nonce"=>1403655423}
# Signed: YjYwMTNjMTkwYjQxYzMwNjhjZmU5NjQyYjVkYmI0ZDk1MmY4NmQzNTg4ZGM1%0ANjFjZGQzYmEwYjVlZDBiMjhmOTMzZjhiODcyOGEyMjM5YWVmOGYxZjQ3ZGZl%0AOTc3NGUzYzVhYzhmMzAwYTBhNzkxYzZhNTQ1Y2U4Y2ZmYmI4MWEK%0A
# 404
# 4: full url requested, with no params specified, path/secret in signature
# URL: https://bittrex.com/api/v1.1/account/getorderhistory?apikey=5231569363514ee....98efb483c25c&nonce=1403655423
# {"apikey"=>"5231569363514ee....98efb483c25c", "nonce"=>"1403655423"}
# Signed: YjYwMTNjMTkwYjQxYzMwNjhjZmU5NjQyYjVkYmI0ZDk1MmY4NmQzNTg4ZGM1%0ANjFjZGQzYmEwYjVlZDBiMjhmOTMzZjhiODcyOGEyMjM5YWVmOGYxZjQ3ZGZl%0AOTc3NGUzYzVhYzhmMzAwYTBhNzkxYzZhNTQ1Y2U4Y2ZmYmI4MWEK%0A
# {"success":false,"message":"INVALID_SIGNATURE","result":null}
# 5: url with no params, params specified, host/path/secret in signature
# URL: https://bittrex.com/api/v1.1//account/getorderhistory
# {"apikey"=>"5231569363514ee....98efb483c25c", "nonce"=>1403655423}
# Signed: ODA3MGU2NmU5MjIxYjdjMWQ3ZDVmY2VjNTJjOGU5ZDg1MWZhOWM2Zjc3MDE5%0ANTcwYTMwZjQxZjgyMTdiMGFiMmNlM2M4YmQzMWJhMDBjMmYxMGMwNTNkMWZk%0ANjMwNjE2ZjE2N2E3MzYyOTdjZTRmMTk4MWIwY2FiZjdmZmEzMDgK%0A
# {"success":false,"message":"INVALID_SIGNATURE","result":null}
# 6: url with no params, params specified, url/secret in signature
# URL: https://bittrex.com/api/v1.1//account/getorderhistory
# {"apikey"=>"5231569363514ee....98efb483c25c", "nonce"=>1403655423}
# Signed: MDMzMjI1M2RkNjY3NTA4YjU0ZjUwMjIwM2MxYzkxYWNhYzQxZGRhMTE0Yzdh%0AOGFkMThlOTYyZTBjNmVmZWE1ZTFiMWQ2MGRkMGZmZmVhMzRjNjc3N2NhNDNl%0AZjE3YjljYzczODRjYTljOGI3MTM3ODc2OWU5ODdjZTkyNWYzZmYK%0A
# {"success":false,"message":"INVALID_SIGNATURE","result":null}
@mr-morkou
Copy link

mr-morkou commented Jul 9, 2017

Solve
get https://bittrex.com/api/v1.1/market/buylimit?apikey=LALA&market=BTC-LTC&quantity=0.4&rate=0.018&nonce=1499617500
nonce to the end
HMAC full url
OpenSSL::HMAC.hexdigest('sha512', secret.encode("ASCII"), FULLURL.encode("ASCII"))

@mr-morkou
Copy link

mr-morkou commented Jul 9, 2017

and + faraday.options.params_encoder = DoNotEncoder

  def connection
      @connection ||= Faraday.new(:url => HOST) do |faraday|
        faraday.request  :url_encoded
        faraday.adapter  Faraday.default_adapter
        # faraday.response :logger
        faraday.options.params_encoder = DoNotEncoder
      end
    end
class DoNotEncoder
      def self.encode(params)
        buffer = ''
        params.each do |key, value|
          buffer << "#{key}=#{value}&"
        end
      return buffer.chop
      end
  end

@tarun1475
Copy link

Look at this function it is working fine for me and tested.

function calculateSign(url){
var sign=crypto.createHmac('sha512',constants.bittrexCredentials.SECRET);

sign = sign.update(url,'ascii');
sign = sign.digest('hex');
return sign;

}
Full Implementation repo : https://github.com/tarun1475/Nodejs-Bittrex-Client

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment