接口加签 & 验签

接口加签和验签流程

为防止中间人攻击和篡改,所有由合作伙伴发起的 API 接口请求都需要在 header 中加入签名参数 X-Fp-Signature。同样的,由 FaTPay 发起的订单状态变更的回调 webhook,也将加入签名参数 X-Fp-Signature

API 请求接口加签

申请集成中,您将生成 APIPrivateKey。API 请求接口的签名就是基于这个 APIPrivateKey 生成,所以请千万注意不要泄漏。

加签步骤

API 接口请求加签主要由以下几个步骤组成。

  1. 获取参数

    • 首先,获取除 X-Fp-Signature 外的公共 header 参数,组成一个数组,并将所有 key 转为小写

    • 其次,获取接口全部请求参数,并加入数组

    • 去掉数组中 key 或 value 为空的 item

  2. 参数排序

    • 按所有参数名的字典序(ASCII码)升序排序,注意只有 key 名进行排序,值不参与排序

  3. 生成待签名字符串

    • 先将排序后的数组转化为参数名=参数值形式,并用&符连接,得到请求参数字符串;

    • 再拼接得到 待签名字符串,规则为:请求方法 + 请求域名 + 请求uri + ? + <请求参数字符串>,请求域名不需要带 http/https

  4. 摘要签名

    • 然后对待签名字符串使用 APIPrivateKeyRSA-SHA256 算法进行摘要签名,生成最终的签名。签名 demo 参见 API 接口加签

  5. 签名赋值

    • 最后,将上一步得到的签名赋值到 header 里的 X-Fp-Signature,对 FaTPay API 接口进行调用。FaTPay 网关收到请求后,会统一使用 APIPublicKey 校验签名,如果通过校验则返回相应的服务端数据。

加签示例

假设我们将对 GET 方法的 testSignature 接口(请注意,该接口仅为示例说明,实际并不存在)参数进行加签。该接口 URI 为 api/testsignature

请求参数如下:

{
  "page": 1,
  "index": null,
  "size": 10
}

公共 header 参数如下:

{
  "X-Fp-Nonce": 748219,
  "X-Fp-Partner-Id": "mqMBpCIP630LJxLY",
  "X-Fp-Timestamp": 1656600459,
  "X-Fp-Version": "v1.0"
}

获取参数

首先,获取除 X-Fp-Signature 外的公共 header 参数,组成一个数组,并将所有 key 转为小写

{
  "x-fp-partner-id": "mqMBpCIP630LJxLY",
  "x-fp-timestamp": 1656600459,
  "x-fp-nonce": 748219,
  "x-fp-version": "v1.0"
}

其次,获取接口全部请求参数,并加入数组

{
  "x-fp-partner-id": "mqMBpCIP630LJxLY",
  "x-fp-timestamp": 1656600459,
  "x-fp-nonce": 748219,
  "x-fp-version": "v1.0"
  "page": 1,
  "index": null,
  "size": 10
}

去掉数组中 key 或 value 为空的 item,得到:

{
  "x-fp-partner-id": "mqMBpCIP630LJxLY",
  "x-fp-timestamp": 1656600459,
  "x-fp-nonce": 748219,
  "x-fp-version": "v1.0"
  "page": 1,
  "size": 10
}

参数排序

接着按所有参数名的字典序(ASCII码)升序排序,得到:

{
  "page": 1,
  "size": 10,
  "x-fp-nonce": 748219,
  "x-fp-partner-id": "mqMBpCIP630LJxLY",
  "x-fp-timestamp": 1656600459,
  "x-fp-version": "v1.0"
}

生成待签名字符串

参数名称及参数值均为大小写敏感

先将格式转化为参数名=参数值形式,并用&符连接,得到请求参数字符串:

page=1&size=10&x-fp-nonce=748219&x-fp-partner-id=mqMBpCIP630LJxLY&x-fp-timestamp=1656600459&x-fp-version=v1.0

再拼接得到 待签名字符串,规则为:请求方法 + 请求域名 + 请求uri + ? + <请求参数字符串>,得到最终待签名的字符串:

GETapi.ramp.fatpay.xyz/api/testsignature?page=1&size=10&x-fp-nonce=748219&x-fp-partner-id=mqMBpCIP630LJxLY&x-fp-timestamp=1656600459&x-fp-version=v1.0

摘要签名

然后对待加签字符串使用 APIPrivateKeyRSA-SHA256 算法进行摘要签名,生成最终的签名:

akZjLiZak0v07CzJoKr7/uKgsAzW2a8DXevy98xg3k6HeOtiU2OyWeEYuQtX/G5EuOs5NeagnIwsIxxiFCQoo6hh2OkgxuEphUQNg1B2HO9cYxpJWRKJfxcf20fJ/OIKFfI75PLMqSGRSmx5tVl+9vP4mBzQwpFtgYok2nrWZU4=

签名赋值

最后,将上一步得到的签名赋值到 header 里的 X-Fp-Signature,对 FaTPay API 接口进行调用

curl -X 'https://api.ramp.fatpay.xyz/api/testsignature?page=1&size=10' \
  -H 'Content-Type: application/json' \
  -H 'X-Fp-Nonce: 748219' \
  -H 'X-Fp-Partner-Id: mqMBpCIP630LJxLY' \
  -H 'X-Fp-Timestamp: 1656600459' \
  -H 'X-Fp-Version: v1.0' \
  -H 'X-Fp-Signature: akZjLiZak0v07CzJoKr7/uKgsAzW2a8DXevy98xg3k6HeOtiU2OyWeEYuQtX/G5EuOs5NeagnIwsIxxiFCQoo6hh2OkgxuEphUQNg1B2HO9cYxpJWRKJfxcf20fJ/OIKFfI75PLMqSGRSmx5tVl+9vP4mBzQwpFtgYok2nrWZU4='

Webhook 回调验签

合作伙伴收到 FaTPay webhook 回调后,必须对收到的回调进行签名校验,通过后方可进行后续相应处理。

在订单流程中,FaTPay 平台会主动调用回调地址。为提供给合作伙伴校验合法请求的能力,增加 webhook 接口中的签名。商户收到 webhook 回调通知后,可使用 FaTPay 提供 WebhookPublicKey 进行验签,校验是否存在参数篡改或伪造。

合作伙伴服务端的具体验签流程和服务端 API 请求的加签流程基本类似。

  1. 获取参数

    • 首先,获取除 X-Fp-Signature 外的,以 X-Fp开头的 header 参数,组成一个数组,并将所有 key 转为小写。查看 header 详情

    • 其次,获取接口全部请求参数,并加入数组

    • 去掉数组中 key 或 value 为空的 item

  2. 参数排序

    • 按所有参数名的字典序(ASCII码)升序排序,注意只有 key 名进行排序,值不参与排序;

  3. 生成待验签字符串

    • 先将排序后的数组转化为参数名=参数值形式,并用&符连接,得到请求参数字符串;

    • 再拼接得到 待签名字符串,规则为:请求方法 + 请求域名 + 请求uri + ? + <请求参数字符串>,请求域名不需要带 http://https://请注意,此处请求域名请求 uri 为合作伙伴的webhook 回调地址

  4. 验证签名

    • 合作伙伴使用 X-Fp-Signature 传过来的值作为待校验的签名,和上述得到的待验签字符串,以及 FaTPay 提供的 WebhookPublicKey 进行RSA-SHA256 算法验签

Last updated