패스워드리스 인증은 비밀번호 없이 사용자 신원을 확인하는 인증 방식으로, 피싱·크리덴셜 스터핑 등 비밀번호 관련 공격을 원천 차단한다.
패스워드리스 방식 비교
| 방식 | 메커니즘 | 보안 수준 | UX |
|---|
| Magic Link | 이메일 OTP 링크 | 중간 | 높음 |
| SMS OTP | 문자 인증코드 | 낮음(SIM 스와핑) | 높음 |
| TOTP | 시간 기반 OTP (Google Auth) | 중간 | 중간 |
| WebAuthn/FIDO2 | 생체/하드웨어 키 | 매우 높음 | 높음 |
| Passkey | WebAuthn + 클라우드 동기화 | 매우 높음 | 매우 높음 |
Magic Link 구현
typescript
// 1. 링크 생성 및 발송
async function sendMagicLink(email: string) {
const token = crypto.randomBytes(32).toString('hex');
const expiresAt = new Date(Date.now() + 15 * 60 * 1000); // 15분
await db.magicTokens.create({
email, token,
expiresAt,
used: false
});
await sendEmail(email, {
subject: '로그인 링크',
body: `https://app.example.com/auth?token=` + token
});
}
// 2. 링크 검증
async function verifyMagicLink(token: string) {
const record = await db.magicTokens.findOne({ token });
if (!record || record.used || record.expiresAt < new Date()) {
throw new Error('유효하지 않은 링크');
}
await db.magicTokens.update({ token }, { used: true });
return createSession(record.email);
}
Passkey (패스키)
Passkey = WebAuthn 자격증명 + 클라우드 동기화
특징:
- 기기 간 동기화 (iCloud Keychain, Google Password Manager)
- 피싱 불가 (도메인 바인딩)
- 생체인증으로 간편 사용
- 비밀번호 완전 대체 가능
지원 플랫폼:
- iOS 16+ / macOS Ventura+: iCloud Keychain
- Android 9+: Google Password Manager
- Windows 11: Windows Hello
TOTP 구현 (RFC 6238)
python
import pyotp, qrcode
# 비밀키 생성
secret = pyotp.random_base32()
totp = pyotp.TOTP(secret)
# QR 코드 생성 (Google Authenticator 등록용)
uri = totp.provisioning_uri(
name="user@example.com",
issuer_name="MyApp"
)
# 검증
def verify_totp(user_code: str, secret: str) -> bool:
totp = pyotp.TOTP(secret)
return totp.verify(user_code, valid_window=1)
# valid_window=1: ±30초 허용
관련 문서
- •[webauthn|[WebAuthn / FIDO2]]
- •[[openid-connect|OpenID Connect]]
- •[[tpm|TPM (신뢰 플랫폼 모듈)]]