admin管理员组文章数量:1344235
I wrote an interface to make requests to the internal audible api with python. Every API request needs to be signed with RSA SHA256.
Now I want to test the endpoints of the API with Postman and make use of the pre request script function. But I'm not firm with javascript. Maybe someone can help me in translate the following python function to a Postman script:
def sign_request(
request: httpx.Request, adp_token: str, private_key: str
) -> httpx.Request:
"""
Helper function who creates a signed requests for authentication.
:param request: The request to be signed
:param adp_token: the token is obtained after register as device
:param private_key: the rsa key obtained after register as device
:returns: The signed request
"""
method = request.method
path = request.url.path
query = request.url.query
body = request.content.decode("utf-8")
date = datetime.utcnow().isoformat("T") + "Z"
if query:
path += f"?{query}"
data = f"{method}\n{path}\n{date}\n{body}\n{adp_token}"
key = rsa.PrivateKey.load_pkcs1(private_key.encode())
cipher = rsa.pkcs1.sign(data.encode(), key, "SHA-256")
signed_encoded = base64.b64encode(cipher)
signed_header = {
"x-adp-token": adp_token,
"x-adp-alg": "SHA256withRSA:1.0",
"x-adp-signature": f"{signed_encoded.decode()}:{date}"
}
request.headers.update(signed_header)
return request
I found out how to get the request method and the body. I can get the path and query with pm.request.url.getPathWithQuery()
. To add the headers to the request I use pm.request.headers.add
.
But I doesn't know how to get the datetime in isoformat, join strings and sign the data.
I wrote an interface to make requests to the internal audible api with python. Every API request needs to be signed with RSA SHA256.
Now I want to test the endpoints of the API with Postman and make use of the pre request script function. But I'm not firm with javascript. Maybe someone can help me in translate the following python function to a Postman script:
def sign_request(
request: httpx.Request, adp_token: str, private_key: str
) -> httpx.Request:
"""
Helper function who creates a signed requests for authentication.
:param request: The request to be signed
:param adp_token: the token is obtained after register as device
:param private_key: the rsa key obtained after register as device
:returns: The signed request
"""
method = request.method
path = request.url.path
query = request.url.query
body = request.content.decode("utf-8")
date = datetime.utcnow().isoformat("T") + "Z"
if query:
path += f"?{query}"
data = f"{method}\n{path}\n{date}\n{body}\n{adp_token}"
key = rsa.PrivateKey.load_pkcs1(private_key.encode())
cipher = rsa.pkcs1.sign(data.encode(), key, "SHA-256")
signed_encoded = base64.b64encode(cipher)
signed_header = {
"x-adp-token": adp_token,
"x-adp-alg": "SHA256withRSA:1.0",
"x-adp-signature": f"{signed_encoded.decode()}:{date}"
}
request.headers.update(signed_header)
return request
I found out how to get the request method and the body. I can get the path and query with pm.request.url.getPathWithQuery()
. To add the headers to the request I use pm.request.headers.add
.
But I doesn't know how to get the datetime in isoformat, join strings and sign the data.
Share Improve this question asked Oct 31, 2020 at 8:20 mkb79mkb79 1881 gold badge1 silver badge8 bronze badges 1- This should help you - blog.kiprosh./… – Mahesh_Loya Commented Oct 31, 2020 at 8:30
2 Answers
Reset to default 5I'm get it running with the pm lib. Thank you for your help.
The only issue is getting the private cert, who contains newlines, from env var gives an error with these code sig.init(privateKey);
. I had to write the private cert string directly in the pre request script.
Here are my script.
eval( pm.globals.get('pmlib_code') );
var CryptoJS = require("crypto-js");
var moment = require("moment");
const adpToken = pm.environment.get("adp-token")
// private-key loaded from env var doesn't work because of newlines in it; bugfix
const privateKey = pm.environment.get("private-key")
// use private-key in pre request script directly make use of newline correctly
const privateKey2 = "-----BEGIN RSA PRIVATE KEY-----\nMIIE...==\n-----END RSA PRIVATE KEY-----\n"
signRequest(pm.request, adpToken, privateKey);
function signRequest(request, adpToken, privateKey2) {
const method = request.method;
const path = request.url.getPathWithQuery();
const body = request.body || "";
const date = moment.utc().format();
const data = `${method}\n${path}\n${date}\n${body}\n${adpToken}`;
var sig = new pmlib.rs.KJUR.crypto.Signature({"alg": "SHA256withRSA"});
sig.init(privateKey);
var hash = sig.signString(data);
const signedEncoded = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(hash));
pm.request.headers.add({
key: 'x-adp-token',
value: adpToken
});
pm.request.headers.add({
key: 'x-adp-alg',
value: 'SHA256withRSA:1.0'
});
pm.request.headers.add({
key: 'x-adp-signature',
value: `${signedEncoded}:${date}`
});
}
UPDATE:
Now reading the device cert from env var works. I had to replace const privateKey = pm.environment.get("private-key")
with const privateKey = pm.environment.get("private-key").replace(/\\n/g, "\n")
The problem to make this in Postman is that you can use only those packages available in sandbox. So for this, you have crypto-js as the unique package helper for crypto operations.
var CryptoJS = require("crypto-js");
var moment = require("moment");
signRequest(pm.request, "yourAdpToken", "yourPrivateKey")
function signRequest(request, adpToken, privateKey) {
const method = request.method;
const path = request.url.getPathWithQuery();
const body = request.body.raw;
const date = moment.utc().format();
const data = `${method}\n${path}\n${date}\n${body}\n${adpToken}`
const hash = CryptoJS.HmacSHA256(data, privateKey);
const signedEncoded = CryptoJS.enc.Base64.stringify(hash);
pm.request.headers.add({
key: 'x-adp-token',
value: adpToken
});
pm.request.headers.add({
key: 'x-adp-alg',
value: 'SHA256withRSA:1.0'
});
pm.request.headers.add({
key: 'x-adp-signature',
value: `${CryptoJS.enc.Base64.parse(signedEncoded)}:${date}`
});
}
Adding the above to the Pre-request Script will add your wanted headers to the request like this:
You may need to change the encode parts, check the encode options
本文标签: javascriptPostman custom signing request with SHA256 and RSAStack Overflow
版权声明:本文标题:javascript - Postman: custom signing request with SHA256 and RSA - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743705277a2525007.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论