JSON Web Signature (JWS)
JSON Web Signature (JWS) là một đặc tả JOSE định nghĩa một cách gọn nhẹ, an toàn cho URL để biểu diễn nội dung đã được ký số. Việc triển khai JWS đảm bảo danh tính người gửi được xác minh và thông điệp không bị thay đổi, cung cấp tính không thể chối bỏ (non-repudiation) cho các tương tác của bạn với Bahn API.
Dưới đây là tóm tắt cách quy trình ký hoạt động:
- Tạo một cặp khóa P-256 và cung cấp public key cho Bahn trong quá trình onboarding.
- Bahn đăng ký public key để API sử dụng.
- Sau khi đăng ký, bạn có thể gọi các endpoint hỗ trợ JWS với request body đã được ký.
- Bahn xác minh chữ ký bằng public key đã đăng ký của bạn và thực hiện thêm các kiểm tra khác, bao gồm tính hợp lệ của header
url.
Cung cấp public key
Public key phải được gửi cho Bahn trong quá trình onboarding. Xem Xác thực để biết đầy đủ các yêu cầu, bao gồm các trường JWK bắt buộc.
Quy trình
Dưới đây là hướng dẫn từng bước để tự xây dựng và gửi một request đã ký bằng JWS.
1. Xây dựng header và payload
Chuẩn bị request body theo tài liệu tham chiếu API, sau đó xây dựng header JWS với các trường bắt buộc. Trường url là bắt buộc — Bahn sử dụng nó để xác nhận request không bị replay sang một endpoint khác.
Header
{
"alg": "ES256",
"iat": 1773220702,
"kid": "client_key",
"typ": "jose+json",
"url": "/bn/api/playground/concat-strings"
}Payload
{
"string1": "Hello",
"string2": "World"
}2. Ký bằng private key của bạn
Mã hóa base64url header và payload, sau đó ký chúng bằng private key P-256 của bạn. Sử dụng một thư viện JOSE đã được kiểm chứng để tránh lỗi mã hóa hoặc ký.
JWS compact kết quả có ba phần cách nhau bởi dấu chấm:
<base64url(header)>.<base64url(payload)>.<signature>Ví dụ
eyJhbGciOiJFUzI1NiIsImlhdCI6MTc3MzIyMDcwMiwia2lkIjoiY2xpZW50X2tleSIsInR5cCI6IkpXUyIsInVybCI6Ii9ibi9hcGkvcGxheWdyb3VuZC9jb25jYXQtc3RyaW5ncyJ9.eyJzdHJpbmcxIjoiSGVsbG8iLCAic3RyaW5nMiI6IldvcmxkIn0.xIY9EZMJTcawCnH7J2NLZO6P66hFfexNU-gJdNqEAuRyHs4szMZLjW--GZ15N_6Q8WYmhY8DX_XVpBySvUigVA3. Gửi request
Bahn hỗ trợ hai content type để gửi request đã ký. Chọn loại phù hợp nhất với hệ thống tích hợp của bạn.
Phương án A: Compact serialization — application/jose
Gửi JWS compact serialization (header.payload.signature) trực tiếp làm request body dưới dạng chuỗi văn bản thuần:
curl -X POST 'https://t.cakedigibank.tech/bn/api/playground/concat-strings' \
-H 'Bn-Api-Key: <your-api-key>' \
-H 'Bn-Jose-Method: jws' \
-H 'Content-Type: application/jose' \
-d 'eyJhbGciOiJFUzI1NiIsImlhdCI6MTc3MzIyMDcwMiwia2lkIjoiY2xpZW50X2tleSIsInR5cCI6Impvc2UranNvbiIsInVybCI6Ii9ibi9hcGkvcGxheWdyb3VuZC9jb25jYXQtc3RyaW5ncyJ9.eyJzdHJpbmcxIjoiSGVsbG8iLCAic3RyaW5nMiI6IldvcmxkIn0.xIY9EZMJTcawCnH7J2NLZO6P66hFfexNU-gJdNqEAuRyHs4szMZLjW--GZ15N_6Q8WYmhY8DX_XVpBySvUigVA'Cấu trúc:
BASE64URL(header) . BASE64URL(payload) . BASE64URL(signature)Phương án B: JSON serialization — application/jose+json
Gửi JWS General JSON Serialization (RFC 7515 Section 7.2) làm request body. Định dạng này tách protected header, payload, và signature thành các trường JSON riêng biệt:
curl -X POST 'https://t.cakedigibank.tech/bn/api/playground/concat-strings' \
-H 'Bn-Api-Key: <your-api-key>' \
-H 'Bn-Jose-Method: jws' \
-H 'Content-Type: application/jose+json' \
-d '{
"payload": "eyJzdHJpbmcxIjoiSGVsbG8iLCAic3RyaW5nMiI6IldvcmxkIn0",
"signatures": [
{
"protected": "eyJhbGciOiJFUzI1NiIsImlhdCI6MTc3MzIyMDcwMiwia2lkIjoiY2xpZW50X2tleSIsInR5cCI6Impvc2UranNvbiIsInVybCI6Ii9ibi9hcGkvcGxheWdyb3VuZC9jb25jYXQtc3RyaW5ncyJ9",
"signature": "xIY9EZMJTcawCnH7J2NLZO6P66hFfexNU-gJdNqEAuRyHs4szMZLjW--GZ15N_6Q8WYmhY8DX_XVpBySvUigVA"
}
]
}'Cấu trúc:
{
"payload": "<base64url(payload)>",
"signatures": [
{
"protected": "<base64url(header)>",
"signature": "<base64url(signature)>"
}
]
}Khi sử dụng
application/jose+jsonvới nhiều chữ ký, Bahn sử dụng mục chữ ký đầu tiên để xác minh.
Khi thành công, Bahn trả về kết quả đã được nối:
{
"result": "HelloWorld"
}