Skip to main content

Encryption

Several fields in M1 do not carry the value you started with. They carry that value encrypted against the ABDM public key. When an API page shows a placeholder such as {{encrypted aadhaar number}}, the field name tells you what the value is and the placeholder tells you it must already be encrypted.

In short​

  • Encrypt the Aadhaar number, mobile number, OTP and password with RSA against the published public key, and send the base64 ciphertext.
  • M1 calls use the ABHA service's key. PHR calls use the PHR key, which is a different key at a different URL.
  • Your system never holds a secret for this: only the current public certificate.

What must be encrypted​

Six kinds of value never travel raw in an M1 request body.

ValueWhere it appears
Aadhaar numberEnrolment and login by Aadhaar
ABHA numberLogin and search by ABHA number
Mobile numberLogin, search and mobile update
Email addressEmail verification
One time password (OTP) valueEvery call that verifies a challenge
PasswordPassword based login

Each is encrypted with RSA using the ABDM public certificate, and the base64 of the ciphertext goes in the field.

What shape the plaintext must be​

The service validates the plaintext after it decrypts, so the shape you encrypt matters and a wrong shape is rejected as though the value were wrong.

ValuePlaintext shapeExample
ABHA number14 digits with dashes, NN-NNNN-NNNN-NNNN91-1234-5678-9015
Aadhaar number12 digits, no spaces999999990019
Mobile number10 digits, first digit 1 to 9, optionally prefixed with +91 or 09876543210
OTP valueExactly 6 digits123456

The ABHA number is the one that catches people, because the number is printed and stored both ways. Encrypting the 14 bare digits is rejected: a login OTP request sent that way on the sandbox on 11 September 2026 returned 400 {"loginId": "LoginId is invalid"}, and the same number encrypted as 91-1234-5678-9015 passed validation and went on to look the account up. Strip the dashes for display if you like, but put them back before you encrypt.

Aadhaar, mobile and OTP values follow the validation patterns given on each call in the M1 API reference.

How the model works​

We publish the public half of a key pair. You encrypt with it. Only our private half can decrypt. Your system never holds a secret to do this, only the current certificate.

There is nothing ABDM specific in the mechanics. Your platform's standard RSA library does the work. Both keys use RSA/ECB/OAEPWithSHA-1AndMGF1Padding. The one thing to confirm is which key you are using.

Where to do it​

Encrypt inside your own system, against the published ABDM public key. This is the production path.

Fetching the public key​

A PHR application fetches its own key from GET /abha/api/v3/phr/app/login/public/certificate, the first call in P1. It is a different key from the ABHA service's, so never encrypt a PHR call with the M1 certificate.

M1 has a public/certificate API for fetching the public key. Its URL, headers and response shape are on the certificate call.

Where to go next​

  • Gateway for the session token every call needs.
  • M1 user journeys, where the encrypted identifier appears in the search and login steps.