Aller au contenu

Envoyer des codes OTP par SMS : le guide de sécurité pour les développeurs

Génération, stockage, expiration, limitation des essais, rédaction du message : comment implémenter des codes de vérification OTP par SMS de façon sécurisée.

Un code OTP (One-Time Password, ou mot de passe à usage unique) envoyé par SMS sert à vérifier qu'un utilisateur possède bien un numéro de téléphone : à l'inscription, à la connexion, ou pour valider une opération sensible. Le principe est simple, mais une implémentation négligée ouvre la porte à la fraude et aux abus. Ce guide détaille une approche sûre, indépendante du langage utilisé.

Le fonctionnement en 4 étapes

  1. L'utilisateur saisit son numéro (ou déclenche une action sensible).
  2. Votre serveur génère un code aléatoire, l'enregistre avec une date d'expiration, et l'envoie par SMS via l'API.
  3. L'utilisateur saisit le code reçu.
  4. Votre serveur compare le code saisi au code enregistré, vérifie qu'il n'a pas expiré et que le nombre d'essais n'est pas dépassé, puis l'invalide.

La plateforme SMS se charge uniquement de l'acheminement. La génération et la vérification restent sous votre contrôle, dans votre application.

1. Générer un code vraiment aléatoire

Utilisez toujours le générateur cryptographique de votre langage, jamais une fonction pseudo-aléatoire classique :

  • PHP : random_int(0, 999999)
  • Python : secrets.randbelow(1_000_000)
  • Node.js : crypto.randomInt(0, 1_000_000)

Complétez à 6 chiffres avec des zéros à gauche (004213). Six chiffres offrent un million de combinaisons : c'est suffisant si le nombre d'essais est limité.

2. Stocker une empreinte, pas le code

Enregistrez une empreinte (hash) du code, par exemple avec HMAC-SHA256 et une clé secrète côté serveur, accompagnée de :

  • l'identifiant de l'utilisateur ou le numéro concerné ;
  • la date d'expiration ;
  • le nombre de tentatives déjà effectuées ;
  • l'objet du code (inscription, connexion, paiement…), pour qu'un code émis pour une action ne serve pas à une autre.

N'écrivez jamais le code en clair dans vos logs, vos outils de suivi d'erreurs ou vos réponses d'API.

3. Fixer une durée de validité courte

5 à 10 minutes suffisent dans la grande majorité des cas. Au-delà, le risque augmente sans bénéfice réel pour l'utilisateur. Un code doit être invalidé dès qu'il a été utilisé avec succès, et remplacé si un nouveau code est demandé.

4. Limiter les essais et les demandes

Deux limites distinctes protègent votre service :

  • Limite d'essais : après 5 codes erronés, le code est invalidé et l'utilisateur doit en demander un nouveau. Sans cette limite, un attaquant peut tester toutes les combinaisons.
  • Limite d'envois : pas plus d'un code par minute et quelques codes par heure pour un même numéro, et une limite par adresse IP. Sans elle, un robot peut vider vos crédits SMS en déclenchant des envois en masse vers des numéros aléatoires.

Ajoutez un délai visible dans l'interface (« Renvoyer le code dans 60 s ») : l'utilisateur comprend pourquoi il doit patienter.

5. Rédiger le message

Un bon SMS de vérification est court, identifiable et met en garde contre la fraude :

Votre code MONAPPLI est 482913. Il expire dans 10 minutes. Ne le communiquez à personne, même à nos équipes.
  • Le nom du service dans le texte, en plus du nom d'expéditeur.
  • Le code bien visible, sans autre chiffre qui puisse prêter à confusion.
  • La durée de validité.
  • Un avertissement : les fraudeurs appellent souvent leurs victimes en se faisant passer pour le service client pour obtenir le code.

6. Prévoir les cas difficiles

  • SMS non reçu : proposez un renvoi après le délai, et vérifiez que le numéro est bien saisi au format international (+225…).
  • Téléphone éteint ou hors couverture : le SMS sera délivré lorsque le téléphone redeviendra joignable, parfois après l'expiration du code. Un nouveau code règle le problème.
  • Changement de numéro : prévoyez une procédure de récupération de compte qui ne repose pas uniquement sur le SMS.

7. Exemple d'envoi avec SMS Gold

Une fois le code généré et son empreinte enregistrée, l'envoi est une simple requête :

curl -X POST https://smsgold.tornixtech.com/api/v2/sms/send \
  -H "Authorization: Bearer $SMSGOLD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":"+2250700000000","message":"Votre code MONAPPLI est 482913. Il expire dans 10 minutes. Ne le communiquez à personne.","sender_name":"MONAPPLI"}'

Des exemples complets existent en PHP, Python et Node.js.

Checklist

  • Code généré avec un générateur cryptographique, 6 chiffres.
  • Empreinte stockée, jamais le code en clair ni dans les logs.
  • Expiration de 5 à 10 minutes, invalidation après usage.
  • 5 essais maximum par code.
  • Limite d'envois par numéro et par IP.
  • Message avec nom du service, durée et avertissement anti-fraude.
  • Clé API stockée côté serveur uniquement.
Tous les articles

Prêt à envoyer vos premiers SMS professionnels ?

Créez votre compte gratuitement, importez vos contacts et préparez vos messages. Vous activez l'envoi quand vous êtes prêt.