Aadhaar Encryption (Fingpay AePS)
The Fingpay AePS APIs accept the Aadhaar number in the aadhar parameter
encrypted, never as plain text. You encrypt it on your backend with an
RSA public key provided by Fingpay, then Base64-encode the result. This
applies only to the Fingpay AePS APIs listed below.
Aadhaar number → UTF-8 bytes → RSA encryption (PKCS#1 v1.5) → Base64 → aadhar
APIs that need an encrypted Aadhaar
| API | Whose Aadhaar |
|---|---|
| Send OTP (eKYC) | Agent |
| Verify OTP (eKYC) | Agent |
| Biometric eKYC | Agent |
| Daily KYC | Agent |
| Cash Withdrawal OTP | Customer |
| AePS Cash Withdrawal | Customer |
| AePS Balance Enquiry | Customer |
| AePS Mini Statement | Customer |
RSA Public Key
Format: Base64-encoded X.509 RSA public key (SubjectPublicKeyInfo, DER).
Fingpay doesn't offer a UAT environment, so there is no UAT key. The production key is in Console → Credentials once your account is active. Keep it in configuration, not in code.
Encryption steps
- Base64-decode the RSA public key.
- Load the decoded bytes as an X.509 RSA public key.
- Convert the 12-digit Aadhaar number to UTF-8 bytes — digits only, no spaces or hyphens.
- Encrypt the bytes with the public key using RSA with PKCS#1 v1.5 padding
(
RSA/ECB/PKCS1Paddingin Java). - Base64-encode the encrypted bytes (the ciphertext).
- Send the resulting string as the
aadharparameter.
Plain Aadhaar
123412341234
↓
UTF-8 bytes
↓
RSA encryption with Fingpay's RSA public key
(PKCS#1 v1.5 padding)
↓
Encrypted bytes
↓
Base64 encoding
↓
nJ8k2...xP4=
↓
Send as the `aadhar` parameter
PKCS#1 v1.5 padding is randomised, so encrypting the same Aadhaar number twice produces different values. This is expected — don't cache or compare the encrypted strings.
The public key can only encrypt. Only the receiving system holds the matching private key that decrypts it. Encrypt as early as possible and never log the plain Aadhaar number.
Code samples
Each sample takes the Aadhaar number and the RSA public key, and
returns the Base64 string to send as aadhar. Run this on your backend.
import crypto from "node:crypto";/** RSA-encrypt (PKCS#1 v1.5) a 12-digit Aadhaar number; returns Base64 ciphertext. */export function encryptAadhaar(aadhaarNumber, rsaPublicKeyBase64) {if (!/^\d{12}$/.test(aadhaarNumber)) throw new Error("Aadhaar must be exactly 12 digits");const encrypted = crypto.publicEncrypt({key: Buffer.from(rsaPublicKeyBase64, "base64"), // Base64-encoded X.509 public keyformat: "der",type: "spki",padding: crypto.constants.RSA_PKCS1_PADDING,},Buffer.from(aadhaarNumber, "utf8"),);return encrypted.toString("base64"); // send as the `aadhar` param}
The encrypted value is standard Base64 and may contain +, / and =. Send
it as a normal JSON string; if you ever place it in a URL or form body,
URL-encode it first (an unescaped + turns into a space).
Troubleshooting
If the API rejects the Aadhaar as incorrectly encrypted, check:
- Wrong key — a key other than the production key from Console → Credentials.
- Wrong padding — OAEP or "no padding" instead of PKCS#1 v1.5. Some libraries default to OAEP; set PKCS#1 v1.5 explicitly.
- Formatted input — spaces, hyphens or a masked number encrypted instead of the plain 12 digits.
- Double encoding — Base64-encoding the Aadhaar before encrypting, or encoding the ciphertext twice.
- Damaged key — line breaks or whitespace copied into the Base64 key string.