I'm computing the HMAC of the HTTP body request in this way:
payload = {"name":"myvm","os":"gentoo","resources":{"vCPU":"4","RAM":"512","Disk":"1000"},"actions":["start"]}
key = "supersecretkey"
secret = bytes(key, encoding='utf-8')
msg = json.dumps(payload, sort_keys=True)
message = bytes(msg, encoding='utf-8')
print(hmac.new(secret, message, sha1).hexdigest())
After that I encode with b64 the hexdigest and send it with curl like the docs says Authorization: paolo:$hmac_base64_encoded
The problem is that I always get a 500 error. What am I doing wrong?
Since you are using Python 3x make sure that in your custom HMACAuth you are converting to bytes (the code snippet from the official documentation is for Python 2x).
Related
I wanted to know how I can validate HTTP messages with JWS Detached. Currently, I am receiving x-sign-jws request in header which looks like below
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..UXwjHxU3tFlrzPMupG04zROiEcHFQpCg3l7J4Axr1fE
I need to verify this at my end whether the request is right or not using my secrete Key
Ex: 12345678
I am using firebase/jwt and tried below code
$hed = getallheaders();
$recievedJwt = $hed["X-Sign-Jws"];
$decoded = JWT::decode($recievedJwt, $secret_key, array('JWT','HS256'));```
but I am not getting any result.
I searched on net I found the article which mentioned below steps:
Validation HTTP message with JWS Detached:
a) Get the HTTP header "x-sign-jws",
b) Get BASE64URL HTTP body
c) Put generate string b) into the Payload section
d) Validate JWS
But I am confused with how to get Base64URL HTTP body
Any help would be greatly appreciated since there are only a few articles available on this topic.
JWS format is base64url(header).base64url(payload).base64url(signature), note the dot delimiter between 3 components.
Detached JWS still contains 3 components but the payload is removed and provided elsewhere, usually the payload is provided in the HTTP Body.
To verify detached JWS, you need to add base64url encoded payload to the detached JWS. The payload is available from your HTTP Body.
For example;
x-sign-jws = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..UXwjHxU3tFlrzPMupG04zROiEcHFQpCg3l7J4Axr1fE
//split x-sign-jws into array using delimiter .
x-sign-jws-attached = x-sign-jws-split[0] + '.' + base64Url(HTTPRequest.Body) + '.' + x-sign-jws-split[1]
Now you can verify x-sign-jws-attached as shown below;
$decoded = JWT::decode($x-sign-jws-attached, $secret_key, array('JWT','HS256'));```
Certain APIs in my project can only be accessed via OAuth 2.0 using an encoded format. I am able to manually submit a POST using POSTMAN as it has the x-www-form-urlencoded feature to send the request (image attached). As a workaround, I created a java function to convert my json body to an encoded URI and passed as a variable. However, I am getting a "http call failed for URL" when running it. I was wondering if Karate has its own library to convert json to Encoded URIs.
Scenario: Json to Encoded URI on POST body
* def JavaDemo = Java.type('com.ge.health.gam.service.servicerequest.testsuite.CustomJavaClass')
* def encodedURI = JavaDemo.jsonToURI()
* print encodedURI
Given url 'http://location.ver02.geicenter.com/uaa/oauth/token'
And request encodedURI
When method post
Then status 200
com.intuit.karate.exception.KarateException: http call failed after 263 milliseconds for URL: http://location.ver02.geicenter.com/uaa/oauth/token
As suggested by Peter Thomas, I found the below to be able to submit requests via Oath 2.0. In my case, I also had to install a required certificate in order to receive a valid response. you also have to take that into consideration.
Given path 'uaa', 'oauth', 'token'
And form field key = 'value'
And form field key = 'value'
And form field key = 'value'
And form field key = 'value'
When method post
Then status 200
Yes. Please refer to the documentation for form field. There is also an OAuth 2 example in the demos, look for it.
Also see: https://stackoverflow.com/a/58643689/143475
In falcon 1.1.0, the only way to send data is through body which takes byte data. How can we post json in such a situation using the simulate_post method while testing falcon APIs using pytest.
Use body to send JSON as a string:
data = json.dumps(data)
client.simulate_request(method='POST', path=url, body=data)
Optionally you can also set the content-type header to indicate it's a JSON request:
headers = {'Content-Type': 'application/json'}
data = json.dumps(data)
client.simulate_request(method='POST', path=url, headers=headers, body=data)
I have the following code and I also read the post from Bittrex. My nonce and apikey are used for HMAC calculation, but I receive the APISIGN_NOT_PROVIDED error.
For this version, we use a standard HMAC-SHA512 signing. Append apikey
and nonce to your request and calculate the HMAC hash and include it
under an apisign header. Note: the nonce is not respected right now
but will be enforced later.
if true
% code
url_base = 'https://bittrex.com/api/v1.1/market/getopenorders';
body = [url_base,'?apikey=',apikey,'&nonce=',nonce];
sign = hmac(secret_key, body, 'SHA-512');
json = urlread( body, 'Get', {'apisign', sign} )
end
Since urlread is not recommended anymore (reference here), just for the sake of curiosity, try the currently recommended alternative webread:
url_base = 'https://bittrex.com/api/v1.1/market/getopenorders/';
url_full = [url_base '?apikey=' apikey '&nonce=' nonce];
sign = hmac(secret_key,url_full,'SHA-512');
opt = weboptions('ContentType','json','HeaderFields',{'apisign' sign},'RequestMethod','get');
json = webread(url_full,opt);
Also, don't forget to put a breakpoint in your code and check how sign looks like, just to be sure you are forwarding properly formatted data in your HTTPS request headers.
I am trying to get a little bit familiar with this REST API:
https://docs.gemini.com/rest-api/#private-api-invocation
However, I am trying to figure out how they do authentication, and it seems they don't use OAuth. This is what they say:
Gemini uses API keys to allow access to private APIs. You can obtain these by logging on and creating a key in Settings/API. This will give you both an "API Key" that will serve as your user name, and an "API Secret" that you will use to sign messages.
All requests must contain a nonce, a number that will never be repeated and must increase between requests. This is to prevent an attacker who has captured a previous request from simply replaying that request. We recommend using a timestamp at millisecond or higher precision. The nonce need only be increasing with respect to the session that the message is on.
Now, I don't understand where to place my API Secret key. They don't really specify a parameter name for it. Same thing goes for the nonce. Also, does the nonce need to be randomized? And what size should the nonce be? I am not that familiar with this.
As described in the docs you linked you need to base64-encode the "request", "nonce" and "order_id" for the X_GEMINI_PAYLOAD header and SHA384 that payload with the API Secret for the X-GEMINI-SIGNATURE header.
Here's an example from the site (Python):
import requests
import base64
import hmac
from hashlib import sha384
url = "https://api.gemini.com/v1/order/status"
gemini_api_key = "mykey"
gemini_api_secret = "1234abcd"
# for the purposes of this example, we've shown hand-rolled JSON - please import json and use json.dumps in your real code!
b64 = base64.b64encode("""{
"request": "/v1/order/status",
"nonce": 123456,
"order_id": 18834
}
""")
signature = hmac.new("1234abcd", b64, hashlib.sha384).hexdigest()
headers = {
'Content-Type': "text/plain",
'Content-Length': "0",
'X-GEMINI-APIKEY': gemini_api_key,
'X-GEMINI-PAYLOAD': b64,
'X-GEMINI-SIGNATURE': signature,
'Cache-Control': "no-cache"
}
response = requests.request("POST", url, headers=headers)
print(response.text)