
Teilen Sie:
Benjamin Aronov ist ein Entwickler-Befürworter bei Vonage. Er ist ein bewährter Community Builder mit einem Hintergrund in Ruby on Rails. Benjamin genießt die Strände von Tel Aviv, das er sein Zuhause nennt. Von Tel Aviv aus kann er einige der besten Startup-Gründer der Welt treffen und von ihnen lernen. Außerhalb der Tech-Branche reist Benjamin gerne um die Welt auf der Suche nach dem perfekten Pain au Chocolat.
SIM-Swap-Betrug mit Go und Vonage aufdecken
Lesedauer: 5 Minuten
Die meisten Online-Konten verlassen sich immer noch auf SMS für die Zwei-Faktor-Authentifizierung (2FA). Aber was passiert, wenn ein Betrüger Ihren Anbieter dazu bringt, Ihre Nummer auf seine SIM-Karte zu übertragen (SIM-Austausch-Angriff)? Plötzlich werden diese Sicherheitscodes, die Sie schützen sollen, zu einem Werkzeug, das gegen Sie eingesetzt wird.
Eine SIM-Swap-Prüfung ersetzt nicht 2FA, sondern teilt Ihrer App mit, ob SMS immer noch ein sicherer Kanal ist, der verwendet werden kann. In diesem Tutorial zeigen wir Ihnen, wie Sie die Identity Insights API von Vonage mit Go (Golang) integriert wird, um SIM-Swaps in Echtzeit zu erkennen und Ihre Nutzer vor Account-Hijacking zu schützen.
>> TL;DR: Holen Sie sich den vollständigen funktionierenden Code auf GitHub.
Voraussetzungen
Um mitzumachen, brauchen Sie:
Ein Vonage Developer Account
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.
Projekt einrichten
Erstellen einer Vonage-Anwendung
Um eine Anwendung zu erstellen, gehen Sie auf die Seite Erstellen einer Anwendung auf dem Vonage Dashboard und legen Sie einen Namen für Ihre Anwendung fest.
Wenn Sie eine API verwenden möchten, die Webhooks nutzt, benötigen Sie einen privaten Schlüssel. Klicken Sie auf "Generate public and private key", der Download sollte automatisch starten. Bewahren Sie ihn sicher auf; dieser Schlüssel kann bei Verlust nicht erneut heruntergeladen werden. Er folgt der Namenskonvention privat_<Ihre App-ID>.key. Dieser Schlüssel kann nun zur Authentifizierung von API-Aufrufen verwendet werden. Hinweis: Ihr Schlüssel funktioniert erst, wenn Ihre Anwendung gespeichert ist.
Wählen Sie die benötigten Funktionen (z. B. Voice, Nachrichten, RTC usw.) und stellen Sie die erforderlichen Webhooks bereit (z. B. Ereignis-URLs, Antwort-URLs oder URLs für eingehende Nachrichten). Diese werden im Lernprogramm beschrieben.
Zum Speichern und Bereitstellen klicken Sie auf "Neue Anwendung generieren", um die Einrichtung abzuschließen. Ihre Anwendung ist nun bereit für die Verwendung mit Vonage-APIs.
Die Identity Insights API ist auf Live-Mobilfunknetzdaten angewiesen, um SIM-Wechsel zu erkennen. Aktivieren von Netzwerk-Registrierung in Ihrer Vonage Anwendung ermöglicht den Zugriff auf diese Datenquelle. In der Produktion erfordert dies die Zustimmung des Betreibers, was einige Zeit in Anspruch nehmen kann, aber im Playground-Modus können Sie sofort mit dem Testen beginnen.
Erstellen Sie dazu eine Vonage-Anwendung im Vonage Dashboard mit:
Netzwerkregistrierungsfunktion aktiviert, und wählen Sie "Playground".
Erzeugen Sie einen privaten.Schlüsselmüssen Sie diesen im folgenden Abschnitt in das Stammverzeichnis verschieben
Einrichten Ihrer Go-App
Führen Sie in Ihrem Terminal die folgenden Befehle aus, um ein Projektverzeichnis und die erforderlichen Dateien zu erstellen:
mkdir go_sim_swap_checker
cd go_sim_swap_checker
touch main.go .env>> Sie können nun Ihre heruntergeladene privat.schlüssel in den go_sim_swap_checker Verzeichnis
Abhängigkeiten installieren
Initialisieren Sie in Ihrem Projektverzeichnis das Go-Modul und installieren Sie die erforderlichen Pakete:
go mod init sim_swap_checker
go get github.com/golang-jwt/jwt/v5
go get github.com/joho/godotenv
go get github.com/google/uuidgolang-jwt: Ermöglicht die Erzeugung von JWT-Token für die API-Authentifizierung
godotenv: Lädt Umgebungsvariablen aus einer .env-Datei
uuid: Erzeugt eindeutige Bezeichner für jedes JWT, damit jedes Token sicher unterschieden werden kann
Konfigurieren Sie Ihr.env Datei
Öffnen Sie die .env-Datei in Ihrem Texteditor und fügen Sie Folgendes hinzu:
VONAGE_APPLICATION_ID=your_application_id
VONAGE_PRIVATE_KEY_PATH=./private.key
PHONE_NUMBER=+990123455
DEFAULT_HOURS=240Fügen Sie Ihre Vonage-Anwendungs-ID, eine Standard-Telefonnummer und den Zeitraum in Stunden für die SIM-Wechselprüfung hinzu.
Die Virtuelle Vermittlungsstelle von Vonage stellt 9 gültige Telefonnummern zur Verfügung, die Sie zum Testen verwenden können, sowie eine, die eine "unbekannte" Antwort liefert.
Sie können in der API-Referenz für Identitätseinblicke sehen Sie, dass der Sim-Swap-Einblick auf einem einzigen Parameter namens ZeitraumWir nennen ihn Stunde und setzen den Standardwert auf 240. Bei einem Wert unter 500 erhält der virtuelle Betreiber die Antwort, dass die SIM-Karte nicht getauscht wurde. Werte über 500 führen zu einer positiven Sim Swap API-Antwort.
Schreiben des Go-Skripts zur Überprüfung eines SIM-Tauschs
Schritt 1: Einrichten der Importe und der Umgebung
Bevor wir API-Anfragen stellen können, müssen wir Go-Pakete für HTTP-Anfragen, JSON-Verarbeitung und die Verwaltung von Umgebungsvariablen einbinden. Außerdem werden wir unsere Anmeldeinformationen aus einer .env-Datei laden, damit wir keine sensiblen Informationen im Skript fest codieren.
package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
"github.com/joho/godotenv"
)
func loadEnv() {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
}
Schritt 2: Authentifizierung mit JWT
Die Identity Insights API verwendet JWT (JSON Web Token) Authentifizierung. Ein JWT beweist Vonage, dass Ihre Anwendung die Erlaubnis hat, die Anfrage zu stellen.
Wir definieren eine Anmeldeinformationen Typ, um die Vonage Anwendungs-ID und den privaten Schlüssel zu speichern, und fügen eine NewCredentials Konstruktor hinzu, um sie zu laden, und verwenden dann eine Einzweckmethode GenerateJWT(ttl) um das Token zu erstellen und zu signieren. Auf diese Weise bleiben Datei-I/O, Validierung und Token-Erstellung sauber getrennt und sind leicht zu testen.
type Credentials struct {
ApplicationID string
PrivateKeyPEM []byte
}
func NewCredentials(applicationID, privateKeyPath string) (*Credentials, error) {
if applicationID == "" {
return nil, fmt.Errorf("missing VONAGE_APPLICATION_ID")
}
if privateKeyPath == "" {
return nil, fmt.Errorf("missing VONAGE_PRIVATE_KEY_PATH")
}
pem, err := os.ReadFile(privateKeyPath)
if err != nil {
return nil, fmt.Errorf("read private key: %w", err)
}
return &Credentials{ApplicationID: applicationID, PrivateKeyPEM: pem}, nil
}
func (c *Credentials) GenerateJWT(ttl time.Duration) (string, error) {
key, err := jwt.ParseRSAPrivateKeyFromPEM(c.PrivateKeyPEM)
if err != nil {
return "", fmt.Errorf("parse rsa key: %w", err)
}
now := time.Now()
claims := jwt.MapClaims{
"iat": now.Unix(),
"exp": now.Add(ttl).Unix(),
"jti": uuid.NewString(),
"application_id": c.ApplicationID,
}
tok := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
signed, err := tok.SignedString(key)
if err != nil {
return "", fmt.Errorf("sign jwt: %w", err)
}
return signed, nil
}
Schritt 3: Definieren von Sim-Swap-Strukturen
Um die JSON-Antwort der API sauber in Go zu verarbeiten, definieren wir eine Reihe von Structs, die die Struktur der SIM-Swap-Daten der Identity Insights API widerspiegeln.
Mit diesen Strukturen können wir die API-Antwort direkt in typisierte Go-Objekte zerlegen, was die Arbeit mit den Daten erleichtert:
type SimSwapStatus struct {
Code string `json:"code"`
Message string `json:"message"`
}
type SimSwapDetails struct {
Swapped *bool `json:"swapped,omitempty"`
LastSimSwapAt string `json:"latest_sim_swap_at,omitempty"`
Status SimSwapStatus `json:"status"`
}
type SimSwapResponse struct {
RequestID string `json:"request_id"`
Insights struct {
SimSwap SimSwapDetails `json:"sim_swap"`
} `json:"insights"`
}
Schritt 4: Core-Sim-Swap-Funktion definieren
Nachdem die Authentifizierung geklärt ist, können wir uns mit der API verbinden. Die Funktion checkSimSwap bringt alles zusammen: Sie akzeptiert eine Telefonnummer, ein Zeitfenster (in Stunden), die API-URL und das JWT-Token, das Sie zuvor erzeugt haben.
Es geht um Folgendes:
Bereiten Sie die Anfrage vor: Erstellen Sie einen JSON-Body, der die Telefonnummer, den Zweck der Betrugsprävention und den Zeitraum des SIM-Tauschs enthält.
Sicherer Versand: Verwenden Sie http.NewRequest um eine POST-Anfrage zu erstellen, fügen Sie den JWT in der Autorisierung Header an und legen Sie den Inhaltstyp fest.
Parsen der Antwort: Dekodieren des JSON in unsere SimSwapResponse Struktur, damit wir mit typisierten Feldern anstelle von rohem JSON arbeiten können.
Interpretieren Sie das Ergebnis: Anhand des Statuscodes (OK, NO_COVERAGE, INTERNAL_ERROR)
func checkSimSwap(phoneNumber, hours, apiURL, jwtToken string) {
reqBody := map[string]interface{}{
"phone_number": phoneNumber,
"purpose": "FraudPreventionAndDetection",
"insights": map[string]interface{}{
"sim_swap": map[string]interface{}{
"period": hours,
},
},
}
body, err := json.Marshal(reqBody)
if err != nil {
log.Fatal("Error marshaling request body:", err)
}
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(body))
if err != nil {
log.Fatal("Error creating request:", err)
}
req.Header.Set("Authorization", "Bearer "+jwtToken)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal("Error sending request:", err)
}
defer resp.Body.Close()
var res SimSwapResponse
if err := json.NewDecoder(resp.Body).Decode(&res); err != nil {
log.Fatalf("Error decoding API response: %v", err)
}
switch res.Insights.SimSwap.Status.Code {
case "OK":
if res.Insights.SimSwap.Swapped != nil {
if *res.Insights.SimSwap.Swapped {
t, err := time.Parse(time.RFC3339, res.Insights.SimSwap.LastSimSwapAt)
formatted := res.Insights.SimSwap.LastSimSwapAt
if err == nil {
formatted = t.Format("January 2, 2006 at 3:04 PM")
}
fmt.Printf("\n🚨 ALERT: SIM swap detected!\nLast swap occurred around: %s\n", formatted)
} else {
fmt.Println("\n✅ No SIM swap detected. The phone number appears to be secure.")
}
} else {
fmt.Println("\n⚠️ Status was OK but swap status was missing.")
}
case "NO_COVERAGE":
fmt.Println("\nℹ️ This phone number is not supported by the SIM swap check service.")
case "INTERNAL_ERROR":
fmt.Println("\n❌ An unexpected error occurred while checking the phone number. Please try again later.")
default:
fmt.Printf("\n❌ An unknown error occurred: %s\n", res.Insights.SimSwap.Status.Message)
}
}
Schritt 5: CLI-Wrapper für Interaktivität
Um das Skript praktisch zu gestalten, verpacken wir es in eine main() Funktion, damit Sie es direkt ausführen können. Der CLI-Wrapper fordert den Benutzer zur Eingabe einer Telefonnummer und eines benutzerdefinierten Zeitraums auf oder greift auf die Standardeinstellung zurück. Er sendet dann die Anfrage an die Identity Insights API durch checkSimSwap an die Identity Insights API und gibt ein eindeutiges Ergebnis auf Ihrem Terminal aus.
Auf diese Weise können Sie verschiedene Numbers und Zeitfenster interaktiv testen, ohne den Code jedes Mal neu bearbeiten zu müssen. Später könnte die gleiche Logik in einen Webdienst oder ein Backend-System integriert werden.
func main() {
loadEnv()
apiURL := "https://api-eu.vonage.com/v0.1/identity-insights"
phoneNumber := os.Getenv("PHONE_NUMBER")
defaultHours := os.Getenv("DEFAULT_HOURS")
applicationID := os.Getenv("VONAGE_APPLICATION_ID")
privateKeyPath := os.Getenv("VONAGE_PRIVATE_KEY_PATH")
creds, err := NewCredentials(applicationID, privateKeyPath)
if err != nil {
log.Fatal("Credentials error:", err)
}
jwtToken, err := creds.GenerateJWT(15 * time.Minute)
if err != nil {
log.Fatal("JWT error:", err)
}
fmt.Println("=== Vonage Identity Insights - SIM Swap Checker ===")
fmt.Printf("Enter phone number [Default: %s]: ", phoneNumber)
var phone string
fmt.Scanln(&phone)
if phone == "" {
phone = phoneNumber
}
fmt.Printf("Enter number of hours to check for SIM swap [Default: %s]: ", defaultHours)
var hours string
fmt.Scanln(&hours)
if hours == "" {
hours = defaultHours
}
checkSimSwap(phone, hours, apiURL, jwtToken)
}
Testen des Skripts
Um das Skript auszuführen, verwenden Sie den folgenden Befehl in Ihrem Terminal:
go run main.go Schlussfolgerung
Mit nur wenigen Zeilen Go und der Vonage Identity Insights API können Sie SIM-Swap-Aktivitäten erkennen, bevor sie sich zu einer umfassenden Account-Übernahme ausweiten. Dieser Ansatz eignet sich perfekt für Tests und kann für die Produktion angepasst werden, sobald Ihre Anwendung bei der Network Registry registriert ist.
Haben Sie eine Frage oder möchten Sie uns mitteilen, was Sie gerade bauen?
Beteiligen Sie sich am Gespräch auf dem Vonage Community Slack
Abonnieren Sie den Entwickler-Newsletter
Folgen Sie uns auf X (früher Twitter) für Updates
Sehen Sie sich die Tutorials auf unserem YouTube-Kanal
Verbinden Sie sich mit uns auf der Vonage Entwickler-Seite auf LinkedIn
Bleiben Sie auf dem Laufenden und halten Sie sich über die neuesten Nachrichten, Tipps und Veranstaltungen für Entwickler auf dem Laufenden.
Teilen Sie:
Benjamin Aronov ist ein Entwickler-Befürworter bei Vonage. Er ist ein bewährter Community Builder mit einem Hintergrund in Ruby on Rails. Benjamin genießt die Strände von Tel Aviv, das er sein Zuhause nennt. Von Tel Aviv aus kann er einige der besten Startup-Gründer der Welt treffen und von ihnen lernen. Außerhalb der Tech-Branche reist Benjamin gerne um die Welt auf der Suche nach dem perfekten Pain au Chocolat.
