首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Postman:使用SHA256和RSA的自定义签名请求

Postman:使用SHA256和RSA的自定义签名请求
EN

Stack Overflow用户
提问于 2020-10-31 16:20:30
回答 2查看 5.2K关注 0票数 1

我编写了一个接口,用python向内部audible api发出请求。每个API请求都需要使用RSA SHA256签名。

现在,我想用Postman测试API的端点,并使用pre request脚本函数。但是我对javascript并不是很坚定。也许有人能帮我把下面的python函数翻译成Postman脚本:

代码语言:javascript
运行
复制
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

我发现了如何获取请求方法和正文。我可以使用pm.request.url.getPathWithQuery()获取路径和查询。为了将头部添加到请求中,我使用了pm.request.headers.add

但我不知道如何获得等格式的日期时间,连接字符串和签名的数据。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-01 00:32:56

在Postman中实现这一点的问题是,您只能使用sandbox中提供的那些包。因此,您可以使用crypto-js作为加密操作的惟一包助手。

代码语言:javascript
运行
复制
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}`
    });
}

将上述代码添加到Pre-request脚本中会将您想要的标头添加到请求中,如下所示:

您可能需要更改编码部分,请检查encode options

票数 1
EN

Stack Overflow用户

发布于 2020-11-01 19:58:46

我要让它和pm lib一起运行。谢谢你的帮助。

唯一的问题是从env var获取包含换行符的私有证书,并使用这些代码sig.init(privateKey);给出错误。我必须在pre request脚本中直接编写私有证书字符串。

这是我的脚本。

代码语言:javascript
运行
复制
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}`
    });
}

更新:

现在可以从env var读取设备证书了。我不得不用const privateKey = pm.environment.get("private-key").replace(/\\n/g, "\n")取代const privateKey = pm.environment.get("private-key")

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64619771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档