.wpb_animate_when_almost_visible { opacity: 1; }

Authentication SMS OTP Consent

Published: July 19, 2024

In order to benefit from the SMS OTP Authentication and Consent, the Service Provider must provide the end-user’s mobile number in his API request. The mobile number must be encoded (see below) added to the request using the login_hint query_string parameter.

## Creating the login_hint for SMS OTP Authentication and ### Consent

The mobile number must be cyphered (see below) and before to be added in the request through the “login_hint” parameter.

The login_hint is formed with the user’s MSISDN and a timestamp. It then is encoded in AES-256-CB.

In order to be added into the URL, the login_hint must be URL encoded.

**Encoding process:**

MSISDN to encode:

msisdn: 33612345678

UNIX Timestamp in millisecondes (i.e. new Date().getTime();)

timestamp: 1453891409214

MSISDN et Timestamp in clear ( timestamp “_” msisdn) (ASCII):


Generation of a 128-bits Initialization Vector for each encoding:

( openssl rand -hex 16 )

Derivation of from the :

key := bin_2_hexa( sha256( ascii_2_binary() ) )
e.g. key = crypto.createHash(“sha256”).update(client_secret).digest();
e.g. (echo -n “clientSecret” |sha256sum) which will give key(hexa)=9a5f75fe98e58215cfdd5b1f64bdb438b7bc6523427224dcc8d8dc0d957eeb86


Login_hint encoded in AES-256-CBC:

AES input (ASCII): “1453891409214_33612345678″
AES key (hexa): 9a5f75fe98e58215cfdd5b1f64bdb438b7bc6523427224dcc8d8dc0d957eeb86
AES IV (hexa): f672e6d89b73dbfb0b97cbe18f89c2ba
openssl aes-256-cbc -v -a -K 9a5f75fe98e58215cfdd5b1f64bdb438b7bc6523427224dcc8d8dc0d957eeb86 -iv f672e6d89b73dbfb0b97cbe18f89c2ba -in clear_1.txt -out cypher_base64_1.txt ; more clear_1.txt ; more cypher_base64_1.txt
AES output (base64): yluZiIzzjjQwwoDq9W0pziedOiWrUTxIXfI9ZfkDhF0=


Adding the Initialization Vector (de 128bits) to the encoded MSISDN in order to form the login_hint:



URL-encoded login_hint :

N.B.: Exemple of encoding using javascript:

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);

N.B.: Exemple of encoding using PHP:

$client_secret = ‘clientSecret’;
$MSISDN = ‘33612345678’;
$login_hint = time()*1000 . ‘_’ . $MSISDN;
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(‘aes-256-cbc’));
$key = hex2bin(openssl_digest($client_secret, ‘sha256’));
$result = openssl_encrypt($login_hint, ‘aes-256-cbc’, $key, 0, $iv);
echo “login_hint : “.bin2hex($iv) . ‘_’ . $result.”\n”;
echo “url encoded login_hint : “.urlencode(bin2hex($iv) . ‘_’ . $result).”\n”;

Your user will be prompted with a UI requesting a SMS-OTP he received on the MSISDN provided in the request.
The SMS-OTP reads as follows:
< Orange Info : Vous recevez ce code (CODE) car (CLIENT_NAME) a formulé une demande d’accès à vos données personnelles. >


As the Client is responsible for collecting and providing the MSISDN into the URL, it is his responsibility to ensure all antispam securities have been set in place in his application/service.
If the Client’s application/service was to be used by a tier to perform an attack of the SMS-OTP authentication system, the service could be temporally suspended for that Client pending the deployment of upgraded securities.