HMAC-SHA512
所有交易类请求(cash-in、cash-out、refund、webhooks)均需要 HMAC-SHA512 签名,以保证载荷的完整性和真实性。
工作原理
- 将请求体序列化为 JSON
- 使用您的
client_secret作为密钥生成 HMAC-SHA512 签名 - 将小写十六进制格式的签名放在
hmac头中发送
API 重新计算哈希并使用恒定时间比较(constant-time comparison)与收到的值进行比对,防止通过时序攻击逐字节推断签名。
HMAC-SHA512 与 Webhook SHA256
API 使用 HMAC-SHA512 来验证您发送的请求。Owem Pay 发送的 Webhook 使用 HMAC-SHA256 进行签名(头 X-Owem-Signature)。它们是不同的算法 -- 各有其使用场景。详见 Webhooks 了解 Webhook 签名验证。
必需的请求头
| 头 | 值 |
|---|---|
Authorization | ApiKey {client_id}:{client_secret} |
Content-Type | application/json |
hmac | 十六进制格式的 HMAC-SHA512 签名 |
示例
JavaScript (Node.js)
javascript
const crypto = require('crypto');
const body = JSON.stringify({
amount: 3000,
pix_key: "12345678901",
pix_key_type: "cpf",
description: "Pagamento"
});
const hmac = crypto
.createHmac('sha512', 'sk_seu-client-secret')
.update(body)
.digest('hex');
// 作为请求头发送: hmac: {value}Python
python
import hmac
import hashlib
import json
body = json.dumps({
"amount": 3000,
"pix_key": "12345678901",
"pix_key_type": "cpf",
"description": "Pagamento"
})
signature = hmac.new(
b"sk_seu-client-secret",
body.encode("utf-8"),
hashlib.sha512
).hexdigest()PHP
php
$body = json_encode([
'amount' => 3000,
'pix_key' => '12345678901',
'pix_key_type' => 'cpf',
'description' => 'Pagamento'
]);
$hmac = hash_hmac('sha512', $body, 'sk_seu-client-secret');Java
java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
String body = "{\"amount\":3000,\"pix_key\":\"12345678901\",\"pix_key_type\":\"cpf\",\"description\":\"Pagamento\"}";
String secret = "sk_seu-client-secret";
Mac mac = Mac.getInstance("HmacSHA512");
SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(), "HmacSHA512");
mac.init(keySpec);
byte[] hash = mac.doFinal(body.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : hash) {
sb.append(String.format("%02x", b));
}
String hmac = sb.toString();C#
csharp
using System.Security.Cryptography;
using System.Text;
var body = "{\"amount\":3000,\"pix_key\":\"12345678901\",\"pix_key_type\":\"cpf\",\"description\":\"Pagamento\"}";
var secret = Encoding.UTF8.GetBytes("sk_seu-client-secret");
using var hmacSha512 = new HMACSHA512(secret);
var hash = hmacSha512.ComputeHash(Encoding.UTF8.GetBytes(body));
var hmac = BitConverter.ToString(hash).Replace("-", "").ToLower();Bash (curl)
bash
BODY='{"amount":3000,"pix_key":"12345678901","pix_key_type":"cpf","description":"Pagamento"}'
SECRET="sk_seu-client-secret"
HMAC=$(echo -n "$BODY" | openssl dgst -sha512 -hmac "$SECRET" | awk '{print $2}')
curl -X POST https://api.owem.com.br/api/external/pix/cash-out \
-H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET" \
-H "Content-Type: application/json" \
-H "hmac: $HMAC" \
-d "$BODY"验证
API 将收到的 HMAC 与请求体进行验证。如果签名不匹配:
json
{
"worked": false,
"detail": "Invalid HMAC signature"
}重要提示
- 请求体必须与发送时完全一致(相同的 JSON 序列化)
- API Key 的
client_secret即为 HMAC 密钥 - 签名必须为小写十六进制格式
- 比较采用恒定时间方式 -- 无法通过时序推断签名