Skip to main content

Overview

FinProServer supports end-to-end encryption on API payloads. When enabled, request bodies must be encrypted before sending, and responses are returned encrypted — protecting sensitive financial data in transit. The encryption scheme uses two layers working together: a symmetric cipher (AES-256-GCM) to encrypt the payload efficiently, and an asymmetric cipher (RSA-OAEP) to securely exchange the symmetric key with the server. The encrypted key bundle sent in each request is called the KEK (Key Encryption Key) — a fresh one is generated per request.

Encryption Architecture

Two layers work together on every request:

Layer 1 — RSA (Key Exchange)

  • Algorithm: RSA-OAEP (SHA-1 hash, 2048/4096-bit key)
  • Encrypts: "key:iv" UTF-8 string
  • Sent in: Request Header → kek

Layer 2 — AES (Payload Encryption)

  • Algorithm: AES-256-GCM
  • Key: 32 bytes · IV: 12 bytes
  • Encrypts: JSON request body
  • Sent in: Request Body → RequestEncryptedValue

Step-by-Step Encryption Process

Perform these 8 steps for every API request:
1

Prepare Your JSON Payload

Serialize your request data to a valid JSON string with UTF-8 encoding.
2

Generate Random AES Key

Generate a cryptographically secure random key:
  • Length: 32 bytes (256 bits)
  • Format: Printable ASCII characters recommended (alphanumeric, no colon)
  • Generate fresh for every request
3

Generate Random IV

Generate a cryptographically secure random IV:
  • Length: 12 bytes (96 bits) — required for AES-GCM
  • Format: Printable ASCII characters (alphanumeric, no colon)
  • Must be unique per request
AES-GCM requires a 12-byte IV. AES-CBC uses 16 bytes — using the wrong size will cause decryption failure on the server.
4

Encrypt Payload with AES-256-GCM

Encrypt your JSON string:
Process:
  1. Encrypt JSON with AES-256-GCM → produces ciphertext + 16-byte auth tag
  2. Base64-encode ciphertext: ct_b64 = base64(ciphertext)
  3. Base64-encode auth tag: tag_b64 = base64(auth_tag) — always 24 characters
  4. Concatenate: encrypted_payload = ct_b64 + tag_b64
Critical: Do NOT prepend the IV to the payload. The IV is transmitted only via the KEK header — the server does not read the IV from the request body. The last 24 characters of the payload string are always the base64-encoded auth tag.
5

Combine Key + IV

Create a single plain UTF-8 string with key and IV separated by a colon:
32 ASCII chars + : + 12 ASCII chars = 45 characters total.
6

RSA-OAEP Encrypt the Key:IV String (Create KEK)

Critical: Do NOT Base64-encode the key:iv string before RSA encryption. Pass the raw UTF-8 bytes of "key:iv" directly to the RSA encrypt function.
7

Base64 Encode the KEK

Example: b85X0Yg0aaWRX969R/51SyUkOBiKCVPk5SmFVmhb+eLBgb4e6OH0UE4RxZia...
8

Build and Send the HTTP Request

Headers:Body:

Request Format

Complete Example

Header Reference

Body Reference

Response Decryption

The server responds with an encrypted payload in the same format:

Decryption Flow

1

Split the payload

Extract the last 24 characters → base64(auth_tag). Everything before = base64(ciphertext).
2

Base64-decode both parts

3

Decrypt with AES-256-GCM

Use the same Key and IV from your original request. GCM verifies the auth tag automatically.
4

Parse JSON

The decrypted bytes are the original plaintext JSON response.
Key points for response decryption:
  • Reuse the same Key and IV you generated for the request — store them after Steps 2 & 3
  • The response format is identical to the request: base64(ciphertext) + base64(auth_tag) — no IV in the payload
  • Auth tag is always the last 24 characters (base64-encoded 16-byte GCM tag)

Prerequisites

Application Registration

Contact FinProServer administrators to register your application. You will receive: Client-side capabilities required:
  • Generate cryptographically secure random bytes (for AES key and IV)
  • AES-256-GCM encryption and decryption
  • RSA-OAEP encryption (asymmetric)
  • Base64 encoding and decoding
  • HTTP requests with custom headers
Recommended libraries:

Algorithm Summary

Encryption Flow Summary

Code Examples

Troubleshooting

Debug Checklist:
  • Server RSA public key is correct and in PEM format
  • Application identifier is registered and matches exactly
  • AES key is exactly 32 bytes (256 bits)
  • IV is exactly 12 bytes (96 bits) — GCM requires 12-byte IV
  • New random Key and IV are generated for every request
  • Request payload is valid JSON before encryption
  • Encrypted payload format: base64(ciphertext) + base64(auth_tag) — NO IV prepended in body
  • KEK input is plain UTF-8 "key:iv" string — NOT Base64-encoded before RSA
  • RSA padding is OAEP with SHA-1 (not PKCS1 v1.5, not SHA-256)
  • RSA-encrypted KEK bytes are Base64-encoded before putting in kek header
  • Both kek and appIdentifier headers are present on every request
  • Request body contains only the RequestEncryptedValue field
  • Same Key and IV are used to decrypt the response
  • Response: last 24 chars = base64(auth_tag); remaining = base64(ciphertext)
  • Auth tag is passed into GCM decrypt — not stripped from the payload first
Common Errors:
Likely cause: Wrong RSA public key, or key:iv was Base64-encoded before RSA encryption.Fix: Use the correct server public key. Pass the raw UTF-8 bytes of "key:iv" directly to RSA encrypt — do not Base64-encode first.
Likely cause: Wrong key/IV used for decryption, or IV was prepended to the payload body.Fix: Do not prepend the IV to the payload — it lives only in the kek header. Use the exact same key + IV from your original request to decrypt the response.
Likely cause: Key is not exactly 32 bytes.Fix: Generate exactly 32 alphanumeric ASCII characters (32 UTF-8 bytes = 256 bits).
Likely cause: Payload parts split incorrectly.Fix: Ensure last 24 chars → auth_tag; all remaining chars → ciphertext. Base64-decode each part separately before passing to GCM.

Appendix

Key Specifications

Encrypted Payload Structure

The IV is NOT part of the payload string. It is embedded only in the KEK header and must be stored by the client to decrypt the response.

Request / Response Body Fields