Generate a pair of public and private JWS keys
Execute this command in your terminal:private_key.pemcontaining your private keypublic_key.pemcontaining your public key
public_key.pem
private_key.pem
Upload your public key to the dashboard
- Go to dashboard.fintoc.com
- Go to the API Keys tab on the side bar
- If products that require JWS are active for your organization, you’ll see a JWS public keys section. Click the “Add JWS Key” button and upload your JWS public key.
Generate a signature
Now that you have uploaded your public key to the Fintoc dashboard, you can generate a signature with your private key. The signature ensures integrity and authenticity for each Transfers API call that moves money.Using our SDK
If you’re using Python or Node, our Python SDK and Node SDK automatically generate the signatures for you. Initialize the Fintoc client with thejws_private_key argument, and the SDK signs each request for you:
Step by step example
If you want to write your own implementation or use a different programming language, follow these steps:Prepare the payload
JWS signature generation operates on the exact JSON string sent in the HTTP request. Create that string by serializing your outbound transfer request body with your language’s JSON serializer.JSON string must be consistentWhen serializing your request body to JSON, you must use the exact same string for two purposes:
- Creating the JWS signature
- Sending as the payload in your HTTP request
Load the private key and configure headers
Load your private key from the PEM file and set up the JWS headers. Headers include the signing algorithm (RS256), a unique nonce to prevent duplicated signatures, the current ts timestamp, and the crit field specification.
Preventing a replay attack
Fintoc uses thenonce and ts timestamp headers in its JWS authentication process to protect against replay attacks and ensure request integrity.
Include a unique, random nonce in every request. This makes each signature distinct, even when the same data is sent multiple times. Fintoc accepts each nonce only once and rejects any request that reuses a nonce.
The ts timestamp records when the request was created, and Fintoc’s servers validate that it falls within a 2-minute window to prevent the processing of outdated requests.
Together, nonce and ts prevent replays: Fintoc rejects any intercepted request that reuses a nonce or falls outside the timestamp window.
Generate the signing input
The signing input for a JWS consists of concatenating the base64url-encodedheaders and the base64url-encoded raw_body with a period . between them, both without padding:
Generate the JWS token signature
Once you have the signing input ready, you’ll create the cryptographic signature using your private key. The process involves:- Sign the signing input with your private key using RSA and PKCS1v15 padding.
- Base64URL-encode the resulting signature, without padding.
Verify the JWS token (optional)
Some libraries re-encode the JSON payload with different spacing, key ordering, or character encoding. To debug the signature, you can inspect the generated token at https://jwt.io to verify its content. We recommend confirming that the JWS token payload matches theraw_body sent in the HTTP request.
Construct the Fintoc-JWS-Signature header
Construct theFintoc-JWS-Signature header by concatenating the protected header and signature:
Complete example
Here is a complete example function that puts it all together. Install the imported libraries before you run it.Test the integration
Confirm your signature works before you go live. Using atest mode API key, sign a create outbound transfer request and send the signature in the Fintoc-JWS-Signature header.
- Build the request body and serialize it to
raw_bodyusing your JSON serializer. - Generate the signature from
raw_bodywith the function above. - Send the request with the
Fintoc-JWS-Signatureheader set to the generated signature.
200 OK and the created transfer when the signature is valid. A signature error or 401 Unauthorized means the signed raw_body does not match the payload in the request body, the nonce was reused, or the ts timestamp falls outside the 2-minute window.