
Teilen Sie:
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!
Erstellen eines "Google Authenticator" vom Festnetz aus mit Vonage
Lesedauer: 22 Minuten
Wir lieben die Zwei-Faktor-Authentifizierung (2FA) - sie macht das Einloggen so viel sicherer, wenn Sie sowohl ein auswendig gelerntes Passwort als auch einen von Ihrem Mobiltelefon generierten Einmal-Passcode verwenden. Das Problem bei guter Sicherheit ist jedoch, dass man sich dadurch sehr leicht aussperren kann.
Stellen Sie sich vor, Sie sind nicht zu Hause - vielleicht im Urlaub oder auf einer Geschäftsreise in einer weit entfernten Stadt. Genau dafür ist 2FA gedacht: Sie können den gemeinsam genutzten Computer in der Hotellobby nutzen, ohne sich vor Keyloggern fürchten zu müssen. Hacker können zwar Ihr Passwort herausfinden, aber ohne das Telefon in Ihrer Hand können sie nicht auf Ihre Daten zugreifen. in Ihrer Hand!

Aber was passiert, wenn Sie Ihr Handy nicht dabei haben? Wenn es verloren geht oder beschädigt oder gestohlen wird? Nun, dann rufen Sie erst einmal Ihre Versicherung an... aber die Kontaktdaten befinden sich auf Ihrem Telefon und in der E-Mail als Backup... und Sie können ohne Ihr Telefon nicht auf Ihre E-Mail zugreifen, da Sie 2FA verwenden! 😱
Wie wäre es, wenn Sie Ihren 2FA-Passcode als Ferndienst abrufen könnten? Sie könnten eine Nummer wählen, Ihre PIN eingeben und sich die Ziffern vorlesen lassen.
Technologischer Hintergrund
Obwohl die ersten Implementierungen proprietär waren, gibt es einen offenen Standard der Initiative for Open Authentication (OATH) für zeitbasierte Einmal-Passwörter (TOTP), der in RFC 6238. Dabei werden ein gemeinsam genutztes Geheimnis und die Anzahl der 30-Sekunden-Ticks seit 1970-01-01 00:00:00 UTC verwendet, ein kryptografischer Hash berechnet und dieser in eine sechsstellige Zahl umgewandelt, die ohne Kenntnis des Geheimnisses nicht vorhergesagt werden kann.
Praktisch ist jedoch ein von Google definiertes URI-Schema. Diese sehen so aus: otpauth://totp/Example:totp@example.com?secret=KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD&issuer=Example
Meistens werden diese URIs als QR-Code kodiert, etwa so:

Voraussetzungen
Für dieses Beispiel brauchen Sie ein paar Dinge:
Google Authenticator (Android/iOS, oder eine ähnliche OATH TOTP-App)
Ein Dienst mit 2FA-Unterstützung (wie z. B. ein Google Account)
An ngrok Account
A Heroku Account
ngrok lokal installiert (ich habe 2.3.35 verwendet)
node.js lokal installiert (ich habe v12.6.1 verwendet)
Vonage API-Konto
Um dieses Tutorial durchzuführen, benötigen Sie ein Vonage API-Konto. Wenn Sie noch keines haben, können Sie sich noch heute anmelden und mit einem kostenlosen Guthaben beginnen. Sobald Sie ein Konto haben, finden Sie Ihren API-Schlüssel und Ihr API-Geheimnis oben auf dem Vonage-API-Dashboard.
In diesem Lernprogramm wird auch eine virtuelle Telefonnummer verwendet. Um eine zu erwerben, gehen Sie zu Rufnummern > Rufnummern kaufen und suchen Sie nach einer Nummer, die Ihren Anforderungen entspricht.
Anmeldung
Wir werden node.js für dieses Beispiel verwenden, weil es damit sehr einfach ist, einen einfachen Webdienst auszuführen. Außerdem gibt es eine sehr schöne Implementierung der Logik für das Einmalpasswort, die wir brauchen: otplib.
Zuerst müssen wir die erforderlichen Bibliotheken installieren, was wir mit npm tun.
Fügen Sie nun den folgenden Code in eine Datei namens totp.js. Wir beginnen mit der Zugangs-PIN und dem gemeinsamen Geheimnis, das dasselbe ist wie der QR-Code oben, und bringen otplib ein.
const totp = require('otplib');
// Hardcoded secrets
const secret = 'KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD';
const pin = '1234';Wir bauen eine einfache node.js Express Webservice, der die Voice API von Vonage verwendet, um den Anruf zu beantworten und ein Nexmo Call Control Object (NCCO) zurückzugeben, das der API mitteilt, dass sie mit Text-to-Speech einen Satz sprechen und dann auf Benutzereingaben über die Telefontastatur warten soll. Dies ist ein sehr einfaches Interactive Voice Response (IVR) System, aber wir werden hier nicht näher darauf eingehen, wie die Voice API funktioniert. Wenn Sie die Funktionsweise dieses Codes genauer verstehen möchten, werfen Sie einen Blick auf dieses Lernprogramm.
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)
}
Jetzt kommt der entscheidende Teil: Wir überprüfen die vom Benutzer eingegebene PIN. Wenn sie korrekt ist, erhalten wir den aktuellen Passcode und lesen ihn vor.
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)
}
}
Schließlich verbinden wir die Funktionen, die wir gerade definiert haben, mit HTTP-Methoden/Pfaden und starten die Anwendung, die auf port 3000.
const PORT = 3000
app
.get('/webhooks/answer', onInboundCall)
.post('/webhooks/passcode', onInput)
app.listen(PORT)Das war's! Sie können dies nun mit node totp.js ausführen und testen, indem Sie zu http://localhost:3000/webhooks/answer in Ihrem Browser aufrufen - es wird das JSON-Objekt aus der onInboundCall Funktion zurück, die wir gerade definiert haben!
Lokale Bereitstellung mit ngrok
Nun, es ist schön, dass etwas läuft, aber es nützt nicht viel, wenn wir nur auf unserem lokalen Rechner darauf zugreifen können!
Die ngrok Dienst bietet eine wunderbare Möglichkeit, einen dynamischen Forwarder einzurichten, um unseren kleinen Dienst über das Internet verfügbar zu machen. Registrieren Sie auf der Website - ein kostenloser Account ist alles, was Sie brauchen - und dann los:
Dadurch werden Ihre Account-Zugangsdaten lokal gespeichert, und Sie können dann die Weiterleitung von HTTP an Port 3000 (den wir oben verwendet haben) einrichten, indem Sie Folgendes ausführen:

Notieren Sie sich die URIs, die angezeigt werden, da diese spezifisch für Ihren Dienst sind und sich jedes Mal ändern, wenn ngrok läuft.
Auch hier können wir dies mit unserem Browser testen, indem wir zu: https://bd934ed5.ngrok.io/webhooks/answer
Hinweis: Sie müssen die URI verwenden, die ngrok bereitstellt.
ngrok bietet uns auch kostenloses HTTPS, so dass unsere Verbindung sicher ist - wie cool ist das denn?
Vonage APIs Einrichtung
Es tut immer noch nicht tun trotzdem nichts. An dieser Stelle wird es gut.
Zunächst müssen wir eine neue Voice API Anwendung erstellen. Gehen Sie dazu auf die Registerkarte "Your applications" des Vonage APIs Dashboard und klicken Sie auf die große Schaltfläche "Create a new application":

Geben Sie einen Namen wie "TOTP-Passcode-Beispiel" ein, und generieren Sie ein Schlüsselpaar, damit es API-Zugriff hat:

Schalten Sie dann die "Voice"-Funktion ein und setzen Sie die Ereignis- (https://bd934ed5.ngrok.io/webhooks/passcode) und Antwort- (https://bd934ed5.ngrok.io/webhooks/answer) URIs auf die von ngrok, die Sie oben notiert haben. Stellen Sie sicher, dass Sie Ihre eigenen ngrok URIs verwenden. Beachten Sie, dass die Ereignis-URI HTTP POST verwendet, so dass Sie dies aus der Dropdown-Liste auswählen müssen:

Wenn Sie lieber eine Befehlszeilenschnittstelle (CLI) verwenden möchten, können Sie alternativ eine Anwendung wie die folgende erstellen.
Installieren Sie die Vonage CLI global mit diesem Befehl:
npm install @vonage/cli -gAls nächstes konfigurieren Sie die CLI mit Ihrem Vonage-API-Schlüssel und -Geheimnis. Sie finden diese Informationen im Entwickler-Dashboard.
vonage config:set --apiKey=VONAGE_API_KEY --apiSecret=VONAGE_API_SECRETErstellen Sie ein neues Verzeichnis für Ihr Projekt und legen Sie eine CD darin ab:
mkdir my_project
CD my_projectVerwenden Sie nun die CLI, um eine Vonage-Anwendung zu erstellen.
Um diesen Dienst anwählen zu können, benötigen wir eine nach außen gerichtete Nummer. Erstellen Sie eine über "Numbers" -> "Buy Numbers" im Dashboard:

Auch hier gibt es für CLI-Fans die Möglichkeit, zunächst nach Voice-fähigen Numbers (z. B. in den USA) zu suchen:
Dann kaufen Sie eines aus der Liste:
Schließlich müssen wir diese Nummer mit dem Antrag verknüpfen. Wenn Sie im Dashboard auf "Meine Applications" gehen und auf Ihre TOTP-Anwendung klicken, sollten Sie am unteren Rand eine Zeile für Ihre Nummer und eine Schaltfläche "Link" unter "Manage" sehen:

Klicken Sie auf "Link" und bestätigen Sie gegebenenfalls:

Keine Angst, CLI-Armee, es gibt auch dafür einen Befehl:
Es gibt auch praktische Befehle, wenn Sie sich nicht mehr an die Telefonnummer (vonage numbers) oder die UUID der Anwendung (vonage apps).
Jetzt haben wir unseren Dienst mit einer Telefonnummer verknüpft. Wenn wir diese Nummer anrufen, wird der /webhooks/answer Endpunkt aus, und das zurückgegebene NCCO löst Text-to-Speech aus, um den Satz "Bitte geben Sie Ihre PIN ein, gefolgt von einer Raute" zu sprechen, und wartet dann auf eine Eingabe über die Telefontastatur. Geben Sie "1234#" auf Ihrer Tastatur ein, und diese Eingabe wird an den Endpunkt gesendet. /webhooks/passcode Endpunkt gesendet, der den sechsstelligen Passcode vorliest.
Scannen Sie den QR-Code oben in diesem Blogbeitrag in Google Authenticator ein, und Sie werden feststellen, dass die Codes perfekt übereinstimmen!
Globale Bereitstellung mit Heroku
Es ist gut, dass wir es zum Laufen gebracht haben, aber es ist nicht sehr praktisch, wenn es auf Ihrem Computer läuft - es hört auf, wenn Sie es ausschalten, und wenn Sie auf Reisen sind, ist es unwahrscheinlich, dass Sie einen Computer zu Hause anlassen! Es wäre also eindeutig besser, wenn wir es irgendwo im Internet laufen lassen könnten.
Heroku ist hierfür gut geeignet, da es die einfache Bereitstellung und das Hosting von Webdiensten ermöglicht. Ein kostenloser Account ist ausreichend, also gehen Sie und anmelden und richten Sie es ein (mit Git und dem Heroku CLI). Ich werde warten.
Code-Änderungen
Heroku weist der Anwendung einen zufälligen Port zum Abhören zu, wir können also nicht einfach 3000 verwenden. Wir müssen diese einzeilige Änderung an totp.js vornehmen, um sie von der Umgebung zu übernehmen:
const PORT = process.env.PORT || 3000Eine weitere Änderung ist in der Datei package.json Datei, damit der npm start Befehl funktioniert, da Heroku sonst nicht weiß, wie es unsere App starten soll! Fügen Sie einfach den node totp.js Befehl, den wir lokal verwendet haben, in das Element scripts ein. Die gesamte package.json sollte nun in etwa so aussehen:
{
"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"
}
Einrichten von Git Source Control
Für die Bereitstellung auf Heroku müssen wir Git verwenden. Außerdem ist es natürlich eine gute Praxis, für jede Entwicklung eine Versionskontrolle einzurichten. Wir werden uns vorerst nur um ein lokales Repository kümmern, aber GitHub ist kostenlos und wird Ihren Code sicher aufbewahren, während er Ihnen von überall auf der Welt zur Verfügung gestellt wird.
Erstellen Sie zunächst ein Repository:
Als nächstes fügen Sie die benötigten Quelldateien hinzu:
Schließlich müssen wir diese Änderungen festschreiben:
Bereitstellen auf Heroku
Zunächst müssen wir eine neue Anwendung in Heroku erstellen:
Dadurch erhält Ihre neue Anwendung einen zufällig generierten Namen, etwa wie lit-spire-15244. Der Befehl heroku create Befehl richtet ein entferntes Repository ein (z.B. https://git.heroku.com/lit-spire-15244.git), in das wir den Code übertragen können.
Um die Anwendung bereitzustellen, müssen wir erneut Git verwenden, um das entfernte Repo zu pushen:
Dadurch wird der Code an Heroku übertragen und ein Deployment ausgelöst. Es wird intern ausgeführt npm start und meldet einen Status wie https://lit-spire-15244.herokuapp.com/ deployed to Heroku. Wenn Sie diese URI verwenden, https://lit-spire-15244.herokuapp.com/webhooks/answerin meinem Fall, sollten Sie sehen, dass der Dienst jetzt läuft. Auch hier haben wir kostenloses HTTPS, was sehr schön ist.
Wenn Sie Probleme haben oder einfach nur sehen wollen, was vor sich geht, können Sie die Protokolle für den Dienst mit dem Befehl anzeigen:
Aktualisieren der Vonage-Anwendung
Schließlich müssen wir das Vonage APIs Dashboard. Gehen Sie auf die Registerkarte "Your Applications", wählen Sie die TOTP-Anwendung aus, klicken Sie auf "Edit" und ändern Sie die URIs:

Nächste Schritte
Wie erhalte ich das Geheimnis für meine Konten?
Leider ist dies bei Google Authenticator und den meisten ähnlichen Apps nicht möglich. Sobald sie einen QR-Code gescannt haben, bieten sie keine Möglichkeit, das Geheimnis abzurufen.
Für G-Suite/Google-Konten (z. B. Gmail) gibt es die Option "Telefon ändern" auf der 2FA-Konfigurationsseitemit der Sie einen neuen QR-Code erhalten können. Bei den meisten anderen Diensten müssen Sie 2FA deaktivieren und dann wieder aktivieren oder Ihren Systemadministrator bitten, dies für Sie zu tun - im Wesentlichen der gleiche Vorgang wie der Austausch Ihres Mobiltelefons.
Wenn Sie einen Screenshot machen und den QR-Code in der App scannen, können Sie das Geheimnis extrahieren und mit dieser Anwendung verwenden.
Wie erhalte ich das Geheimnis eines QR-Codes?
Verwenden Sie eine allgemeine QR-Code-Scanner-Anwendung, um die URI zu erhalten - es gibt viele für alle Handys, und vielleicht ist sogar eine in die Kamera-App Ihres Handys integriert. Alternativ können Sie auch eine Website wie https://webqr.com/ um ein Foto zu scannen.
Das Geheimnis, das Sie benötigen, ist die Folge von Großbuchstaben zwischen "secret=" und dem "&" im URI: otpauth://totp/Example:totp@example.com?secret=KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD&issuer=Example
Wohin können wir das bringen?
Es gibt viele Möglichkeiten, auf dieser Beispielanwendung aufzubauen:
Hardcodierte Geheimnisse zu verlangen ist nicht optimal und es wäre viel besser, sie von einer serverseitigen Datenbank abzurufen
Es gibt keinen Schutz gegen das Aushebeln Ihrer PIN, wenn jemand 10.000 Anrufe bei dieser Anwendung tätigen möchte, daher wäre eine Art Ratenbegrenzung sinnvoll.
Es ist verschwenderisch, eine Telefonnummer für nur ein Geheimnis zu haben, also könnten wir ein IVR-Menüsystem aufbauen ("Drücken Sie 1 für den Gmail-Passcode, drücken Sie 2 für...")
Die Passwörter sind zeitabhängig. Wenn es also nur ein paar Sekunden dauert, bis sich der Code ändert, sollten wir wahrscheinlich Text-to-Speech verwenden, um das zu sagen und auf den nächsten Code zu warten, anstatt einen veralteten Code vorzulesen. Es ist besser, den Anruf um ein paar Sekunden zu verlängern, als die Wahl zu wiederholen und es erneut zu versuchen.
Das manuelle Auslesen von QR-Codes ist ätzend und es gibt node.js-Module (z.B. qrcode-reader), die das für uns erledigen können. Wenn wir die Anwendungsgeheimnisse in einer Datenbank speichern würden, könnten wir ein einfaches Web-Frontend hinzufügen, mit dem man sich über einen Screenshot anmelden kann (z. B. diese Anleitung von Google)
... oder durch Zugriff auf die Kamera des Telefons und ein wenig HTML5-Kleber, um ein Bild zu erfassen (z.B. getUserMedia) oder sogar den QR-Code zu analysieren (z.B. dieses Tutorial oder html5-qrcode) und rufen Sie den Webdienst für die Registrierung auf
Ich hoffe, dass Sie einige Ideen erhalten haben, wie Sie Vonage-APIs mit Zwei-Faktor-Authentifizierung verwenden können.
Teilen Sie:
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!
