mariodian/Geary

I have a problem, the code does not work, or I do something wrong.

Closed this issue · 1 comments

Hello. If I use a class without changing anything, I always get a response error 400

Error: <html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.8.0</center>
</body>
</html>

If I change the method and send the parameters as in example 3 of the documentation on the site, I always get an error that the signature is not correct

https://admin.gear.mycelium.com/docs/api/signed_request
Example3

require 'openssl'
sha512 = OpenSSL::Digest::SHA512.new

secret = '5ioHLiVwxqkS6Hfdev8pNQfhA9xy7dK957RBVYycMhfet23BTuGUPbYxA9TP6x9P'
nonce = 1442215362723 # (Time.now.to_f * 1000).to_i
body = '{"amount":1,"keychain_id":1}'
nonce_body_hash = sha512.hexdigest(nonce.to_s + body.to_s)
nonce_body_hash == "5e587ea40fc9f5a04746aac4f2c90c78fe49cd24d2d208d12732101e0a5c12f00583655925228c25fe68a1197b5b3e478b75a4351bb38d95c18353f3d6bfe569"
request = "POST/gateways/6930af63a087cad5cd920e12e4729fe4f777681cb5b92cbd9a021376c0f91930/orders" + nonce_body_hash
signature = OpenSSL::HMAC.hexdigest(sha512, secret, request)
signature == "4d1e6b02f30aa6ca0c0fafeedea3e785ad9929a7bb8645c2621413abfebf68323791ae6bb76e8374b48db09c4bfdba4c083c5916de2f0f582ac68a32cefe63f1"

# $ curl -H "Content-Type: application/json" -H "X-Nonce: 1442215362723" -H "X-Signature: 4d1e6b02f30aa6ca0c0fafeedea3e785ad9929a7bb8645c2621413abfebf68323791ae6bb76e8374b48db09c4bfdba4c083c5916de2f0f582ac68a32cefe63f1" -X POST -d '{"amount":1,"keychain_id":1}' 'https://gateway.gear.mycelium.com/gateways/6930af63a087cad5cd920e12e4729fe4f777681cb5b92cbd9a021376c0f91930/orders'
# {"status":0,"amount":438481,"address":"mwtoSKLYQiAXtm2h7JV4aZtrixNjzESbYB","tid":null,"id":2564,"payment_id":"35bf5bd6aafcadf336be042582203e94211844c973ef67e83f681a9e2b907dd0","amount_in_btc":"0.00438481","amount_paid_in_btc":"0.0","keychain_id":1,"last_keychain_id":1}

slightly changed the code

    private function prepare_header($data)
    {        
        $params = $data['params'];		
        $params_query = !is_array($params) ? "/$params" : '?' . http_build_query($params);
        $nonce = (int) round(microtime(true) * 1000);
        $body = '{"amount":1,"keychain_id":1}';
        $nonce_hash = hash('sha512', (string) $nonce . $body );
        $payload = $data['request_method'] . $data['request_uri']  . $nonce_hash;
        $raw_signature = hash_hmac('sha512', $payload, $this->gateway_secret);
        $signature = ($raw_signature);
		
	return array(
            'X-Nonce: ' . $nonce,
            'X-Signature: ' . $signature,
	    'Content-Type: application/json' 
    	);
    }
  
    private function send_signed_request($data) {
    	$ch = curl_init();
    	$url = self::API_URL . $data['request_uri'];
    	$headers = $this->prepare_header($data);
        $params = $this->get_params($data['params']);
		
	$data = array("amount" => "1", "keychain_id" => "1");                                                                    
	$data_string = json_encode($data);

        $curl_data = array(
            CURLOPT_URL             => $url,
            CURLOPT_RETURNTRANSFER  => TRUE,
            CURLOPT_HTTPHEADER      => $headers,
            CURLOPT_SSL_VERIFYPEER  => true,
            CURLOPT_CONNECTTIMEOUT  => self::CONNECT_TIMEOUT,
            //CURLOPT_POST            => ($data['request_method'] === 'POST'),
	    CURLOPT_CUSTOMREQUEST   => "POST",
	    CURLOPT_POSTFIELDS      => $data_string
    	);
    	
	curl_setopt_array($ch, $curl_data);
    	if (!$result = curl_exec($ch)) {
            return $this->curl_error($ch);
    	}
    	elseif (curl_getinfo($ch, CURLINFO_HTTP_CODE) !== 200) {
    	    echo "Error: $result";
            
            return FALSE;
    	} else {
            return json_decode($result);
    	}
    }

I get the result:

$nonce:1504345529885;
$nonce_hash:8c009c511f8518c8636f893b01571388858bcf8fed050a34b94b1f378618bfb899891de13c4512bc1697be37bf4bf31fac43e8522f620f262a48ee80e59e3655;
$payload:POST/gateways/XXXXXXXXXXXXXXX/orders8c009c511f8518c8636f893b01571388858bcf8fed050a34b94b1f378618bfb899891de13c4512bc1697be37bf4bf31fac43e8522f620f262a48ee80e59e3655;
$signature:96218a892856424976e228c915668d9951d4f9029ed6effb5a0a01e48b8782c5b5c455dcf13213a4d199fff9158762999d3db97953f94ff9bb699bebf7ce94b3;

curl_data
Array ( [10002] => https://gateway.gear.mycelium.com/gateways/XXXXXXXXXXXXX/orders 
[19913] => 1 
[10023] => Array ( 
                               [0] => X-Nonce: 1504345529885 
                               [1] => X-Signature: 96218a892856424976e228c915668d9951d4f9029ed6effb5a0a01e48b8782c5b5c455dcf13213a4d199fff9158762999d3db97953f94ff9bb699bebf7ce94b3 
                               [2] => Content-Type: application/json
                              )
[64] => 1 
[78] => 60 
[10036] => POST 
[10015] => {"amount":"1","keychain_id":"1"} ) 
/curl_data

Response
Error: X-Signature is invalid: "96218a892856424976e228c915668d9951d4f9029ed6effb5a0a01e48b8782c5b5c455dcf13213a4d199fff9158762999d3db97953f94ff9bb699bebf7ce94b3"

if I use the data from Example 3 on the site https://admin.gear.mycelium.com/docs/api/signed_request

secret = '5ioHLiVwxqkS6Hfdev8pNQfhA9xy7dK957RBVYycMhfet23BTuGUPbYxA9TP6x9P'
nonce = 1442215362723
body = '{"amount":1,"keychain_id":1}'

I get the same signatures that are specified in the example, so the algorithm works correctly, if my data, I always get X-Signature is invalid.

I generated the secret key several times and nothing helped. Site support is not responding.
Thank you for your work, I hope for your help.

Hi, I went through your code and have no idea what could go wrong. Is it possible for you to check the original code on Apache? I had more people telling me the code doesn't work for them on nginx.