Authentication SMS OTP Consent
Published: January 27, 2025
In order to benefit from the SMS OTP Authentication and Consent, service providers must provide the end-user’s mobile number in their API request. The mobile number must be encoded (see below) added to the /authorize
authorization request:login_hint
. This is a query string type parameter whose value is an encryption of the MSISDN to which we wish to send the SMS.
Creating the login_hint
for SMS OTP Authentication
Consent
Several rules apply when creating a login_hint
:
- The
login_hint
consists of the MSISDN and a timestamp, all encrypted in AES-256-CBC, with the Initialization vector in the header. - The
login_hint
is encrypted by the Client and decrypted by the Authorization Server. - To be conveyed in the URL, the
login_hint
is url-encoded.
Example of encoding process
The table below displays the encoding process, so all steps must be followed sequentially:
Element | Value |
---|---|
MSISDN to encode | 33612345678 |
UNIX Timestamp in milliseconds (i.e. new Date().getTime(); ) | 1453891409214 |
MSISDN and Timestamp in plain text (timestamp "_" msisdn ) (ASCII): | 1453891409214_33612345678 |
Generation of a 128-bits Initialization Vector for each encoding: | f672e6d89b73dbfb0b97cbe18f89c2baopenssl rand -hex 16 |
Derivation of <key> from the <client_secret>: | key := bin_2_hexa( sha256( ascii_2_binary(<client_secret>) ) ) command here is: key = crypto.createHash("sha256").update(client_secret).digest(); |
Login_hint encoded in AES-256-CBC: | AES input (ASCII): "1453891409214_33612345678" AES key (hexa): 617a65727479617a65727479617a65727479617a65727479617a65727479617a AES IV (hexa): f672e6d89b73dbfb0b97cbe18f89c2ba AES output (base64): CxaTp04yCdvx8JAqNHdGCK7GGObeGrGBCUvHtcXv1Nk= (BASE64 version "/" and "+") openssl aes-256-cbc -v -a -K 617a65727479617a65727479617a65727479617a65727479617a65727479617a -iv f672e6d89b73dbfb0b97cbe18f89c2ba -in clear_1.txt -out cypher_base64_1.txt ; more clear_1.txt ; more cypher_base64_1.txt AES works in blocks of 128b (16hex). The plain text is 256 bits, the encrypted text is 384 bits because of the PKCS#7 padding which adds 128 bits when the size of the data before padding is already a multiple of the block size |
Addition of the 128-bit Initialization Vector to the encoded MSISDN to form the login_hint | f672e6d89b73dbfb0b97cbe18f89c2ba_CxaTp04yCdvx8JAqNHdGCK7GGObeGrGBCUvHtcXv1Nk= |
URL-encoded login_hint | f672e6d89b73dbfb0b97cbe18f89c2ba_CxaTp04yCdvx8JAqNHdGCK7GGObeGrGBCUvHtcXv1Nk%3D |
Deciphering of the URL-encoded login_hint
of the previous example
openssl aes-256-cbc -v -d -a -K 617a65727479617a65727479617a65727479617a65727479617a65727479617a -iv f672e6d89b73dbfb0b97cbe18f89c2ba -in cypher_base64_1.txt -out decypher_1.txt ; more cypher_base64_1.txt ; more decypher_1.txt
Example of JavaScript cipher
var cryptoModule = require('crypto'), //http://nodejs.org/api/crypto.html
loginHint="msisdn_value", // A valoriser Exemple: 33112233445
timestamp = new Date().toISOString(),
iv = cryptoModule.randomBytes(16),
key = cryptoModule.createHash("sha256").update("client_Secret").digest(); // Valoriser client_secret : password du partenaire
console.log("key=" + key.toString('hex'));
console.log("iv=" + iv.toString('hex'));
var cryptoCipher = cryptoModule.createCipheriv("aes-256-cbc", key,iv),
cypheredLoginHint = cryptoCipher.update(timestamp+"_"+loginHint,'utf8', 'base64') + cryptoCipher.final('base64'),
finalcypheredLoginHint = encodeURIComponent(iv.toString("hex")+"_"+cypheredLoginHint);
console.log("cypheredLoginHint = " + cypheredLoginHint);
console.log("finalcypheredLoginHint = " + finalcypheredLoginHint);
Links to APIs

Match ID France
Cross check your customer information with ours, to mitigate fraud while improving user experience.

Form ID France
Speed up enrollment on a third-party site by automatically populating forms

Home Verify France
Transmit to service providers a digitized (mobile or web) bill from Orange customers as proof of residence