Bitcoin Forum

Economy => Exchanges => Topic started by: matte99 on November 23, 2013, 02:54:55 PM



Title: Bitstamp Private API signature
Post by: matte99 on November 23, 2013, 02:54:55 PM
Hello everyone,

I'm writing a simple Java program that uses Bitstamp API's to manage my account.
To use the private API's I need to send a signature; now on the website they provide a python code snippet that shows how to encode signatures (Here under Api Authentication (https://www.bitstamp.net/api/).
I wrote a java code that does exactly the same (tested it against the python code and the two outputs are identical) but when I try it I still get an "Invalid signature error" from bistamp.

I tried opening a ticket in the Bitstamp support area but it hasn't been replied in days.

Anyone having a similar problem? Or anyone who solved it? I would be glad if someone who has the api working could post a combination of (fake) nonce,signature,key and secret and the relative encoded signature so that I can see if I get the same results.

Thanks!


Title: Re: Bitstamp Private API signature
Post by: matte99 on November 25, 2013, 01:54:40 PM
anyone??  ::)


Title: Re: Bitstamp Private API signature
Post by: Rannasha on November 25, 2013, 02:51:23 PM
Hey,

I have an unfinished project that talks to the Bitstamp API. I've convinced it to show me the relevant data using dummy credentials.

I've generated a call for a list of transactions. The full POST-data is:

Code:
offset=0&limit=100&sort=desc&nonce=1385390835&signature=696E087F4B1902AA58D35E75B4600580D70A92ED68B23379373117FB3FE3064A&key=apiKeyDEMO

So if we break it down to the relevant authentication parameters:
Code:
key = apiKeyDEMO
secret = apiSecretDEMO
clientid = 12345
nonce = 1385390835
signature = 696E087F4B1902AA58D35E75B4600580D70A92ED68B23379373117FB3FE3064A

Hope this helps. If not, post your code so we can take a look at it.


Title: Re: Bitstamp Private API signature
Post by: matte99 on November 25, 2013, 10:23:09 PM
Thank you very much for your help.
I have tried with your data and the signature comes out different from yours. Strange that it was ok with the python code on Bitstamp website. Maybe  I'm malforming the message?

So here's the code I'm using:

Code:
key = "apiKeyDEMO";
secret="apiSecretDEMO";
nonce = 1385390835;

String message = nonce + 12345 + key;

Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(this.secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secretKey);
byte[] hash = sha256_HMAC.doFinal(message.getBytes());
String signature = Hex.encodeHexString(hash).toUpperCase();

my signature comes out to be
Quote
CC78BD37757238B803924846D32742477B3B091C48C21AB05949A7515C3EB7A1


Title: Re: Bitstamp Private API signature
Post by: Rannasha on November 26, 2013, 02:29:26 PM
Thank you very much for your help.
I have tried with your data and the signature comes out different from yours. Strange that it was ok with the python code on Bitstamp website. Maybe  I'm malforming the message?

So here's the code I'm using:

Code:
key = "apiKeyDEMO";
secret="apiSecretDEMO";
nonce = 1385390835;

String message = nonce + 12345 + key;

Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(this.secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secretKey);
byte[] hash = sha256_HMAC.doFinal(message.getBytes());
String signature = Hex.encodeHexString(hash).toUpperCase();

my signature comes out to be
Quote
CC78BD37757238B803924846D32742477B3B091C48C21AB05949A7515C3EB7A1

My Java is a little bit rusty, but in the following line:
Code:
String message = nonce + 12345 + key;
you're adding up 2 integers and a string. Does that work properly in Java? I can imagine you'd need to explicitly convert the ints to strings first.


Title: Re: Bitstamp Private API signature
Post by: matte99 on November 26, 2013, 04:33:12 PM
My Java is a little bit rusty, but in the following line:
Code:
String message = nonce + 12345 + key;
you're adding up 2 integers and a string. Does that work properly in Java? I can imagine you'd need to explicitly convert the ints to strings first.
you're totally right. + is left associative so written like that it didn't work because it did integer addition first and then conversion to string, finally strings concatenation.

However, my original code saves the client ID within a constant of type String.
Also, simply replacing
Code:
 String message = nonce + 12345 + key 
with
Code:
 String message = nonce + "" + 12345 + key 

does the trick and I get the same exact signature you are getting.

However, if I change the values of key,secret and client ID to suit my needs, I still get an invalid signature.

I have tried deactivating that api key and generate a new pair of key-secret but nothing changed. Response is always:

Quote
{"error": "Invalid signature"}


And Bitstamp support sucks since they haven't replied in 5 days


Title: Re: Bitstamp Private API signature
Post by: Rannasha on November 27, 2013, 01:36:42 PM
What's the string you're POST'ing to Bitstamp? Perhaps there's a formatting error there.

Note that I can't guarantee that my example is 100% correct, it's an old project that I haven't worked on recently that I quickly tweaked to show the signature-string. This project did manage to send successful API calls to Bitstamp before.


Title: Re: Bitstamp Private API signature
Post by: matte99 on November 27, 2013, 01:59:12 PM
The code I'm using to post the string is the following:


Code:

String query = "key="+key;
query += "&";
query += "nonce="+nonce;
query += "&";
query += "signature="+signature;

SSLContext sslctx = SSLContext.getInstance("SSL");
sslctx.init(null, null, null);

HttpsURLConnection.setDefaultSSLSocketFactory(sslctx.getSocketFactory());

URL url = new URL("https://www.bitstamp.net/api/balance/");

HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);

PrintStream ps = new PrintStream(con.getOutputStream());
ps.println(query);
ps.close();
con.connect();

if (con.getResponseCode() == HttpsURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new
InputStreamReader(con.getInputStream()));
String text;
while((text = br.readLine()) != null) {
json += text;
}
br.close();
}else{
;
}
con.disconnect();
System.out.println("Code Response: " + con.getResponseCode());



Thank you very much for your help!


Title: Re: Bitstamp Private API signature
Post by: Last_shot on February 07, 2014, 10:29:44 PM
PrintStream is a cause of this issue following code works fine:

private String doPost(String urlString, Map<String,String> params) throws IOException, NoSuchAlgorithmException, KeyManagementException {
      //"param1=a&param2=b&param3=c"
      StringBuilder urlParameters = new StringBuilder();
      
      for (String key : params.keySet()) {
         if(urlParameters.length() > 0) {
            urlParameters.append("&");
         }
         urlParameters.append(key).append("=").append(URLEncoder.encode(params.get(key)));
      }
      
      String query = urlParameters.toString();

   
      URL url = new URL("https://www.bitstamp.net/api/balance/");

      HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
      
      //add reuqest header
      con.setRequestMethod("POST");
   
      // Send post request
      con.setDoOutput(true);
      DataOutputStream wr = new DataOutputStream(con.getOutputStream());
      wr.writeBytes(query);
      wr.flush();
      wr.close();


      String json = "";
      if (con.getResponseCode() == HttpsURLConnection.HTTP_OK) {
         BufferedReader br = new BufferedReader(new
         InputStreamReader(con.getInputStream()));
         String text;
         while((text = br.readLine()) != null) {
            json += text;
         }
         br.close();
      }else{
         ;
      }
      con.disconnect();
      System.out.println("Code Response: " + con.getResponseCode());
      return json;
      

   }


Title: Re: Bitstamp Private API signature
Post by: rudolfpolzer on March 10, 2014, 04:55:24 PM
I tried this with the query string
query =
"key=...&signature=...&nonce=1394469877081"

I replaced here the key and signature text by dots

I got as return string
json =
"{"error": "API key not found"}"

I verified that the API key in the query string is correct (32 characters).
So what is wrong?

edit: I solved this - the API key activation was missing, the code is ok.