2μ°¨ μΈμ¦ μ€μ μ μν QR μ½λ
μ€λμ 2μ°¨ μΈμ¦ μ€μ κ³Όμ μμ OTP μ±μΌλ‘ μ€μΊν μ μλλ‘ μ½λ λμ μ μ 곡νλ QR μ½λμ λν΄μ μμλ³΄λ €κ³ νλ€.
RFC 6238
Google Authenticator, Microsoft Authenticator κ·Έλ¦¬κ³ Authyμ κ°μ OTP μΈμ¦ μ±λ€μ RFC6238λ‘ μ μλ TOTP νμ€μ λ°λΌ ꡬνλμ΄μκ³ QR μ½λμ ν¬ν¨λλ ν μ€νΈλ Key Uri Formatλ‘ κ΅¬μ±λμ΄μΌ μ½μ μ μλ€.
# otpauth://TYPE/LABEL?PARAMETERS
otpauth://totp/Mambo:kdevkr@email.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=Mambo&algorithm=SHA1&digits=6&period=30
TOTP QR μ½λ μ΄λ―Έμ§ λ§λ€κΈ°
QR μ½λ μ΄λ―Έμ§λ₯Ό λ§λ€κΈ° μν΄μ java-totp λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ €κ³ νλ€. μ΄ λΌμ΄λΈλ¬λ¦¬λ λΉλ°ν€ λ°κΈλΆν° QR μ½λλ₯Ό HTMLμμ μ¬μ©νκΈ° μν Data URIλ‘ λ³ννλ Utils.getDataUriForImage ν¨μλ μ 곡ν΄μ£Όκ³ μλ€.
dependencies {
implementation 'dev.samstevens.totp:totp:1.7.1'
implementation 'com.google.zxing:javase:3.5.3'
}
SecretGenerator secretGenerator = new DefaultSecretGenerator();
String secret = secretGenerator.generate();
QrData qrData = new QrData.Builder()
.label("kdevkr@gmail.com")
.secret(secret)
.issuer("Mambo")
.algorithm(HashingAlgorithm.SHA1)
.digits(6)
.period(30)
.build();
ZxingPngQrGenerator qrGenerator = new ZxingPngQrGenerator();
qrGenerator.setImageSize(250);
byte[] qrImageBytes = qrGenerator.generate(qrData);
String qrDataUri = Utils.getDataUriForImage(qrImageBytes, qrGenerator.getImageMimeType());
System.out.println(qrDataUri);
Zxing Decoder Onlineμ μ¬μ©νμ¬ μ¬λ°λ₯΄κ² μ΄λ―Έμ§κ° λ§λ€μ΄μ‘λμ§ νμΈν΄λ³Ό μ μμ΅λλ€.
보μ μ΄μ
2μ°¨ μΈμ¦ μ€μ μ μν΄μ μ 곡νλ QR μ½λμλ μνΈνλμ§ μμ μνμ 보μν€κ° ν¬ν¨λμ΄μλ€. μλ νν°μΈ OTP μ±μ QR μ½λλ₯Ό μ€μΊνμ¬ ν¬ν¨λ ν μ€νΈμμ μ 보λ₯Ό μΆμΆν΄μΌνλ―λ‘ λ³΄μν€λ₯Ό μνΈν ν μλ μλ€. μλμ κ°μ΄ two-factor-authμ²λΌ QR μ½λ μ΄λ―Έμ§ μμ±μ μν΄μ μΈλΆ μ£Όμμ μμ‘΄νλ κ²μ μ’μ§ μλ€.
public static String qrImageUrl(String keyId, String secret, int numDigits, int imageDimension) {
StringBuilder sb = new StringBuilder(128);
sb.append("https://chart.googleapis.com/chart?chs=" + imageDimension + "x" + imageDimension + "&cht=qr&chl="
+ imageDimension + "x" + imageDimension + "&chld=M|0&cht=qr&chl=");
addOtpAuthPart(keyId, secret, sb, numDigits);
return sb.toString();
}
ꡬκΈμμ QR μ΄λ―Έμ§ μμ±μ μ 곡νλ μ£Όμλ μ κ±°λμκ³ λ체ν μ μλ μ£Όμκ° μμ§λ§ μΈλΆ μ£Όμμ 보μν€λ₯Ό μ λ¬νλ κ²μ κΆμ₯νμ§ μμ΅λλ€.