
Partager:
Russ has been arguing with computers since 1985, and now mostly wins the fights. He has worked in video games, defence and investment banking, and joined the Vonage team four days before the Coronavirus lockdown. He enjoys travel, poker, games of all sorts, science fiction, and is easily dist... ooh, squirrel!
Créer un "Google Authenticator" à partir d'une ligne fixe avec Vonage
Temps de lecture : 23 minutes
Nous adorons l'authentification à deux facteurs (2FA) : l'utilisation d'un mot de passe mémorisé et d'un code d'accès à usage unique généré par votre téléphone portable rend la connexion tellement plus sûre. Le problème d'une bonne sécurité, cependant, c'est qu'il est très facile de s'enfermer à l'extérieur.
Imaginez que vous êtes loin de chez vous, en vacances ou en voyage d'affaires dans une ville lointaine. Vous pouvez utiliser l'ordinateur partagé dans le hall de l'hôtel sans avoir peur des enregistreurs de frappe. Les pirates peuvent obtenir votre mot de passe, mais ils ne peuvent toujours pas accéder à vos données sans le téléphone dans votre main!

Mais que se passe-t-il si vous n'avez pas votre téléphone portable ? S'il est perdu, endommagé ou volé ? Eh bien, vous voudrez appeler votre assureur pour commencer... mais les coordonnées sont sur votre téléphone et dans votre email comme sauvegarde... et vous ne pouvez pas accéder à votre email sans votre téléphone puisque vous utilisez le 2FA ! 😱
Et si vous pouviez accéder à votre code d'accès 2FA en tant que service à distance ? Vous pourriez composer un numéro, saisir votre code PIN et vous faire lire les chiffres.
Contexte technologique
Bien que les premières mises en œuvre aient été propriétaires, il existe une norme ouverte de l'Initiative for Open Authentication (OATH) pour les mots de passe à usage unique basés sur le temps (TOTP), spécifiée dans le document RFC 6238. Cette norme prend un secret pré-partagé et le nombre de ticks de 30 secondes depuis 1970-01-01 00:00:00 UTC, calcule un hachage cryptographique et le transforme en un nombre à six chiffres qui ne peut être prédit sans connaître le secret.
Ce qui rend l'utilisation pratique, cependant, c'est un schéma URI défini par Google. Il se présente comme suit : otpauth://totp/Example:totp@example.com?secret=KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD&issuer=Example
Le plus souvent, ces URI sont codés sous la forme d'un code QR, comme celui-ci :

Conditions préalables
Vous aurez besoin de quelques éléments pour cet exemple :
Google Authenticator (Android/iOSou toute autre application OATH TOTP similaire)
Un service prenant en charge le 2FA (tel qu'un Compte Google)
Un ngrok Account
A compte Heroku Account
ngrok installé localement (j'ai utilisé la version 2.3.35)
node.js installé localement (j'ai utilisé la version 12.6.1)
Vonage API Account
To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.
This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.
Applications
Nous allons utiliser node.js pour cet exemple parce qu'il est très facile d'exécuter un simple service web. Il y a aussi une implémentation assez sympa de la logique de mot de passe à usage unique dont nous avons besoin : otplib.
Tout d'abord, nous devons installer les librairies nécessaires, ce que nous faisons avec npm.
Placez maintenant le code suivant dans un fichier appelé totp.js. Nous commencerons par le code PIN d'accès et le secret partagé, qui est le même que celui du code QR ci-dessus, et nous ajouterons otplib.
const totp = require('otplib');
// Hardcoded secrets
const secret = 'KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD';
const pin = '1234';Nous allons construire un simple node.js Express utilisant l'API Voice de Vonage pour répondre à l'appel et renvoyer un Nexmo Call Control Object (NCCO) indiquant à l'API d'utiliser la synthèse vocale pour prononcer une phrase et attendre la saisie de l'utilisateur via le clavier du téléphone. Il s'agit d'un système de réponse vocale interactive (IVR) très simple, mais nous n'allons pas nous étendre sur le fonctionnement de l'API Voice ici. Si vous souhaitez comprendre plus en détail ce que fait ce code, jetez un coup d'œil à ce tutoriel.
const app = require('express')()
const bodyParser = require('body-parser')
app.use(bodyParser.json())
const onInboundCall = (request, response) => {
const ncco = [
{
action: 'talk',
text: 'Please enter your PIN, followed by a hash.'
},
{
action: 'input',
eventUrl: [`${request.protocol}://${request.get('host')}/webhooks/passcode`]
}
]
response.json(ncco)
}
Nous passons maintenant à la partie critique : nous vérifions le code PIN saisi par l'utilisateur. S'il est correct, nous obtiendrons le code d'accès actuel et le lirons à l'utilisateur.
const onInput = (request, response) => {
const dtmf = request.body.dtmf;
if (dtmf === pin) {
const token = totp.authenticator.generate(secret);
const slow = token.split('').join('. ');
const ncco = [{
action: 'talk',
text: `Passcode is ${slow}. Repeat. ${slow}.`
}]
response.json(ncco)
} else {
const ncco = [{
action: 'talk',
text: `Incorrect PIN. Goodbye.`
}]
response.json(ncco)
}
}
Enfin, nous connectons les fonctions que nous venons de définir aux méthodes/chemins HTTP et démarrons l'application en écoutant sur port 3000.
const PORT = 3000
app
.get('/webhooks/answer', onInboundCall)
.post('/webhooks/passcode', onInput)
app.listen(PORT)Voilà, c'est fait ! Vous pouvez maintenant l'exécuter avec node totp.js et le tester en allant sur http://localhost:3000/webhooks/answer dans votre navigateur - il retournera l'objet JSON de la fonction onInboundCall que nous venons de définir !
Déploiement local avec ngrok
C'est bien que quelque chose fonctionne, mais cela ne sert pas à grand-chose si nous ne pouvons y accéder que sur notre machine locale !
Les ngrok est un excellent moyen de mettre en place un transitaire dynamique pour rendre notre petit service disponible sur Internet. Il suffit de s'inscrire sur le site web - un compte gratuit suffit - et de lancer sur le site web - un Account gratuit est tout ce dont vous avez besoin - et ensuite exécutez :
Cela sauvegardera les informations d'identification de votre Account localement, et vous pourrez ensuite configurer la redirection de HTTP vers le port 3000 (celui que nous avons utilisé ci-dessus) en exécutant :

Notez les URIs qu'il affiche car ils seront spécifiques à votre service et changeront à chaque fois que ngrok s'exécutera.
A nouveau, nous pouvons tester ceci avec notre navigateur en allant sur : https://bd934ed5.ngrok.io/webhooks/answer
Note : Vous devez utiliser l'URI fourni par ngrok.
ngrok nous offre également le HTTPS gratuit, de sorte que notre connexion sera sécurisée - c'est vraiment génial !
Configuration des API de Vonage
Il ne fait toujours pas rien rien du tout. C'est ici que ça devient intéressant.
Tout d'abord, nous devons créer une nouvelle application Voice API. Allez dans l'onglet "Vos applications" du tableau de bord des tableau de bord API de Vonage et cliquez sur le gros bouton "Create a new application" :

Saisissez un nom tel que "TOTP Passcode Example", et générez une paire de clés pour qu'il puisse avoir accès à l'API :

Activez ensuite la fonction "Voice" et définissez les URI d'événement (https://bd934ed5.ngrok.io/webhooks/passcode) et de réponse (https://bd934ed5.ngrok.io/webhooks/answer) en fonction des URI de ngrok que vous avez notés ci-dessus. Veillez à utiliser vos propres URI de ngrok. Notez que l'URI d'événement utilise HTTP POST, vous devrez donc le sélectionner dans la liste déroulante :

Si vous préférez utiliser un CLI, vous pouvez créer une application comme celle-ci.
Installez le CLI de Vonage globalement avec cette commande :
npm install @vonage/cli -gEnsuite, configurez le CLI avec votre clé et votre secret API Vonage. Vous pouvez trouver ces informations dans le tableau de bord du développeur.
vonage config:set --apiKey=VONAGE_API_KEY --apiSecret=VONAGE_API_SECRETCréez un nouveau répertoire pour votre projet et placez-y un CD :
mkdir my_project
CD my_projectMaintenant, utilisez le CLI pour créer une application Vonage.
Pour pouvoir composer ce service, nous avons besoin d'un numéro orienté vers l'extérieur. Créez-en un en utilisant "Numbers" -> "Acheter des Numbers" dans le tableau de bord :

Là encore, pour les amateurs de CLI, il est possible de rechercher d'abord les numéros compatibles avec la voix (par exemple, aux États-Unis) :
Ensuite, achetez l'un des produits de la liste :
Enfin, nous devons lier ce numéro à l'application. Si vous allez dans "Mes Applications" dans le tableau de bord et que vous cliquez sur votre application TOTP, vous devriez voir une ligne en bas pour votre numéro et un bouton "Lier" sous "Gérer" :

Cliquez sur "Lien" et confirmez si nécessaire :

N'ayez crainte, armée CLI, il y a une commande pour cela aussi :
Il existe également des commandes pratiques si vous ne vous souvenez pas du numéro de téléphone (vonage numbers) ou de l'UUID de l'application (vonage apps).
Notre service est maintenant associé à un numéro de téléphone. Si nous appelons ce numéro, il déclenchera le point de terminaison et le NCCO renvoyé déclenchera la synthèse vocale pour prononcer la phrase "Veuillez saisir votre code PIN suivi d'un hachage. /webhooks/answer et le NCCO renvoyé déclenchera la synthèse vocale pour prononcer la phrase "Veuillez saisir votre code PIN, suivi d'un dièse", puis attendra la saisie sur le clavier du téléphone. Saisissez "1234#" sur votre clavier, ce qui sera envoyé au point d'accès, qui lira le code PIN. /webhooks/passcode qui lira le code d'accès à six chiffres.
Scannez le code QR en haut de cet article de blog dans Google Authenticator, et vous devriez constater que les codes correspondent parfaitement !
Déploiement mondial avec Heroku
C'est une bonne chose, mais ce n'est pas très pratique de le faire tourner sur votre machine - il s'arrêtera si vous l'éteignez et si vous êtes en voyage, il est peu probable que vous laissiez un ordinateur allumé à la maison ! Il serait donc préférable de le faire fonctionner quelque part sur l'internet.
Heroku est idéal pour cela, car il permet de déployer et d'héberger facilement des services web. Un Account gratuit suffit, alors allez-y et s'inscrire et configurez-le (avec Git et le CLI Heroku). J'attends.
Modifications du code
Heroku attribuera un port aléatoire pour que l'application écoute, nous ne pouvons donc pas simplement utiliser 3000. Nous devons faire ce changement d'une ligne à totp.js pour le récupérer dans l'environnement :
const PORT = process.env.PORT || 3000Une autre modification doit être apportée au fichier package.json pour que la commande npm start car Heroku ne saura pas autrement comment démarrer notre application ! Il suffit d'ajouter la commande node totp.js que nous avons utilisée localement à l'élément scripts. L'ensemble du fichier package.json devrait maintenant ressembler à ceci :
{
"name": "totp",
"version": "1.0.0",
"description": "One Time Password by phone",
"main": "totp.js",
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"nexmo": "^2.6.0",
"otplib": "^12.0.1"
},
"devDependencies": {},
"scripts": {
"start": "node totp.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Russ Williams",
"license": "ISC"
}
Mise en place du contrôle de source Git
Nous devons utiliser Git pour déployer sur Heroku, et c'est évidemment une bonne pratique que d'avoir un contrôle de source en place pour tout développement. Pour l'instant, nous nous contenterons d'un dépôt local, mais GitHub est gratuit et gardera votre code en sécurité tout en le rendant accessible de n'importe où dans le monde.
Tout d'abord, créez un référentiel :
Ensuite, ajoutez les fichiers sources dont nous aurons besoin :
Enfin, nous devons valider ces modifications :
Déploiement sur Heroku
Tout d'abord, nous devons créer une nouvelle application dans Heroku :
Cela donnera à votre nouvelle application un nom généré de manière aléatoire, quelque chose comme lit-spire-15244. La commande heroku create met en place un dépôt distant (par ex. https://git.heroku.com/lit-spire-15244.git) vers lequel nous pouvons pousser du code.
Pour déployer l'application, nous devons à nouveau utiliser Git pour pousser vers ce repo distant :
Cela poussera le code vers Heroku, et déclenchera un déploiement. Il exécutera en interne npm start et rapportera un statut comme https://lit-spire-15244.herokuapp.com/ deployed to Heroku. Si vous utilisez cet URI, https://lit-spire-15244.herokuapp.com/webhooks/answerdans mon cas, vous devriez voir que le service est maintenant en cours d'exécution. Une fois de plus, nous disposons d'une connexion HTTPS gratuite, ce qui est appréciable.
Si vous avez des problèmes, ou si vous voulez simplement savoir ce qui se passe, vous pouvez consulter les journaux du service à l'aide de la commande :
Mise à jour de l'Applications Vonage
Enfin, nous devons mettre à jour le tableau de bord tableau de bord des API de Vonage. Allez dans l'onglet "Your Applications", choisissez l'application TOTP, cliquez sur "Edit" et changez les URI :

Prochaines étapes
Comment obtenir le secret de mes Account ?
Malheureusement, Google Authenticator et la plupart des applications similaires ne le permettent pas. Une fois qu'ils ont scanné un code QR, ils ne permettent pas de récupérer le secret.
Pour les comptes G-Suite/Google (par exemple Gmail), il existe une option "Changer de téléphone" sur la page de configuration du page de configuration 2FAqui vous permet d'obtenir un nouveau code QR. Pour la plupart des autres services, vous devrez désactiver puis réactiver l'option 2FA, ou demander à l'administrateur de votre système de le faire pour vous.
Faire une capture d'écran ainsi que scanner le code QR dans l'application vous permettra d'extraire le secret et de l'utiliser avec cette application.
Comment obtenir le secret d'un code QR ?
Utilisez une application générique de scanner de code QR pour obtenir l'URI - il en existe de nombreuses pour tous les téléphones, et il peut même y en avoir une intégrée à l'application appareil photo de votre téléphone. Vous pouvez également utiliser un site web tel que https://webqr.com/ pour scanner une photo.
Le secret dont vous avez besoin est la séquence de lettres majuscules entre "secret=" et le "&" dans l'URI : otpauth://totp/Example:totp@example.com?secret=KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD&issuer=Example
Où pouvons-nous aller ?
Il existe de nombreuses façons de développer cet exemple d'application :
Exiger des secrets codés en dur n'est pas optimal et il serait préférable de les récupérer à partir d'une base de données côté serveur.
Il n'existe aucune protection contre le forçage brutal de votre code PIN si quelqu'un est prêt à effectuer 10 000 appels à cette application, il serait donc utile de mettre en place une sorte de limitation du taux d'appels
Il est inutile d'avoir un numéro de téléphone pour un seul secret, nous pourrions donc créer un système de menu IVR ("Appuyez sur 1 pour le code Gmail, appuyez sur 2 pour...").
Les codes d'accès sont sensibles au temps, donc s'il ne reste que quelques secondes avant que le code ne change, nous devrions probablement utiliser la synthèse vocale pour dire cela et attendre le prochain, plutôt que de lire un code périmé. Il vaut mieux prolonger l'appel de quelques secondes que de devoir recomposer le numéro et réessayer.
L'extraction manuelle de secrets à partir de codes QR craint et il existe des modules node.js (e.g. qrcode-reader) qui peuvent le faire pour nous. Si nous stockions les secrets de l'application dans une base de données, nous pourrions ajouter un simple front-end web pour s'inscrire à partir d'une capture d'écran (par ex. ce guide de Google)
... ou d'un accès à l'appareil photo du téléphone et d'un peu de colle HTML5 pour capturer une image (par ex. getUserMedia) ou même analyser le code QR (par ex. ce tutoriel ou html5-qrcode) et appeler le service web d'inscription
J'espère que cela vous a donné quelques idées sur la façon dont vous pouvez utiliser les API de Vonage avec l'authentification à deux facteurs.
Partager:
Russ has been arguing with computers since 1985, and now mostly wins the fights. He has worked in video games, defence and investment banking, and joined the Vonage team four days before the Coronavirus lockdown. He enjoys travel, poker, games of all sorts, science fiction, and is easily dist... ooh, squirrel!
