MFA & Passwordless

🔥 Vibe Prompt

"Implement TOTP MFA, WebAuthn passkeys, and risk-based authentication."

TOTP (Time-based One-Time Password)

import pyotp
import qrcode

# Generate secret
secret = pyotp.random_base32()
print(f"Secret: {secret}")

# Create provisioning URI (for QR code)
totp = pyotp.TOTP(secret)
uri = totp.provisioning_uri(name="alice@example.com", issuer_name="MyApp")
print(f"QR URI: {uri}")

# Generate QR code
qr = qrcode.make(uri)
qr.save("totp_qr.png")

# Verify
code = input("Enter TOTP code: ")
if totp.verify(code):
    print("✅ TOTP valid!")
else:
    print("❌ Invalid code")

# Verify with drift tolerance (30s window)
if totp.verify(code, valid_window=1):
    print("✅ Valid within 30s window")

WebAuthn / Passkeys

// Registration (browser)
const credential = await navigator.credentials.create({
  publicKey: {
    challenge: new Uint8Array([...]),  // From server
    rp: { name: "MyApp", id: "example.com" },
    user: {
      id: new Uint8Array([1,2,3]),
      name: "alice@example.com",
      displayName: "Alice"
    },
    pubKeyCredParams: [{ type: "public-key", alg: -7 }],  // ES256
    authenticatorSelection: {
      authenticatorAttachment: "platform",  // Built-in (Touch ID, Face ID)
      residentKey: "required",  // Discoverable credential
      userVerification: "required"
    }
  }
});

// Authentication
const assertion = await navigator.credentials.get({
  publicKey: {
    challenge: new Uint8Array([...]),  // From server
    rpId: "example.com",
    allowCredentials: [{type: "public-key", id: credentialId}],
    userVerification: "required"
  }
});

Risk-Based Authentication (RBA)

def calculate_risk(user, request):
    score = 0
    
    # Location
    if request.geo.country != user.known_countries:
        score += 30
    
    # Device
    if request.user_agent not in user.known_devices:
        score += 20
    
    # Time
    if 2 <= datetime.now().hour <= 5:  # 2-5 AM
        score += 15
    
    # IP reputation
    if is_vpn_or_tor(request.ip):
        score += 25
    
    # Failed attempts
    if user.failed_logins_last_hour > 3:
        score += 10
    
    # Decision
    if score > 70:
        return "BLOCK"
    elif score > 40:
        return "CHALLENGE_MFA"  # Require MFA
    else:
        return "ALLOW"

MFA Methods Comparison

| Method | UX | Security | Phishing Resistant | |--------|-----|----------|--------------------| | TOTP (Google Auth) | Medium | High | No | | SMS (SMS OTP) | Good | Low | No | | Push (Duo) | Good | High | No | | WebAuthn/Passkeys | Best | Highest | Yes | | Security Key (FIDO2) | Medium | Highest | Yes |

Best Practices

  • Offer WebAuthn as primary (best UX + security)
  • TOTP as fallback
  • Avoid SMS MFA (SS7 attacks, SIM swap)
  • Require MFA for all admin/privileged actions
  • Step-up auth for sensitive operations (payments)
  • Remember trusted devices (cookie + device fingerprint)


MFA 與無密碼認證

為什麼需要 MFA?

密碼是安全性最低的認證方式——使用者用 weak password、不同網站用相同密碼、釣魚郵件騙取密碼。MFA(多因子認證)加上第二層驗證(手機驗證碼、指紋、硬體金鑰),讓單一密碼外洩不足以登入。

MFA 的類型

| MFA 類型 | 安全性 | 使用者體驗 | 成本 | |:--------|:------|:---------|:----| | SMS 驗證碼 | 低(SIM Swap 攻擊) | 中 | 低 | | TOTP(Google Authenticator) | 中 | 高 | 免費 | | 推播通知 | 中高 | 高 | 中 | | FIDO2 / WebAuthn | 高 | 高(不用輸入驗證碼) | 中 | | 硬體金鑰(YubiKey) | 最高 | 高 | 高 |

無密碼認證的趨勢

WebAuthn(FIDO2)讓使用者可以用生物辨識(指紋、Face ID)或硬體金鑰登入——完全不需要密碼。無密碼認證正在逐步取代傳統的帳號密碼登入方式。

下一章預告:IAM 稽核

MFA 確保登入安全。下一章的稽核確保操作可以被追蹤——誰在什麼時間做了什麼變更。

解鎖完整教學內容

本章為付費內容。加入專案即可解鎖超過 5000 字的深度解析,包含 10 個以上神級 Prompt 與真實 Source Code 範例!