多因素身份验证(MFA)指南 标题:
一、引言
什么是 MFA? 多因素身份验证(Multi-Factor Authentication, MFA)是一种安全机制,要求用户提供两种或多种形式的身份证据来证明他们是合法用户。常见的形式包括:密码(知识因子)、物理令牌或智能手机应用生成的一次性密码(拥有因子)、生物特征识别(生物特征因子)等。二、MFA 校验流程
初始化设置
登录目标账户(例如阿里云账号或其他在线服务)。
寻找并进入账户安全设置或相关页面以启用 MFA。
选择使用虚拟 MFA(如基于 RFC 6238 的 TOTP 应用)。
下载并安装支持 MFA 的应用程序,如 Google Authenticator、FreeOTP 或 Microsoft Authenticator。
扫描显示的二维码或手动输入共享密钥到应用程序中创建新的 MFA 配置。
日常使用
输入用户名和密码后,系统会提示输入由 MFA 应用生成的动态验证码。
在 MFA 应用中获取当前的有效验证码,并将其准确无误地输入到网站或应用的验证框内。
git addgit commit -m “Merge upstream changes and resolve conflicts”plaintext
三、常见问题与解决方案
:::常见问题与解决方案
::: [火箭] MFA 验证码校验不通过
问题描述 :如果输入的验证码无法通过验证,请确认以下几点:
验证码是否已过期(通常每 30 秒或 60 秒更新一次)。
是否从正确的 MFA 设备获取了验证码。
是否针对同一账户进行验证。
如有变更,确保已在新设备上重新绑定 MFA。 ::: ::: [火] 重置或解绑 MFA
当丢失设备或需要更换 MFA 方式时,需通过账户管理后台的安全措施来进行 MFA 重置或解除绑定。
通常这一步骤可能需要进行身份验证的备份方法,如接收短信验证码或电子邮件确认。 ::: :::
四、最佳实践
启用 MFA 的重要性
强烈建议所有用户启用 MFA,因为它极大地提高了账户安全性,防止恶意攻击者仅凭单一密码窃取账户控制权。 备用验证方式
始终保持至少一种备用验证方式的更新,以便在主 MFA 设备不可用时能访问账户。 [魔法棒挥动] 实用教程 建议先看一下阮一峰老师的 2FA 教程。
双因素认证(2FA)教程
1、各大 MFA 程序的识别的信息的规则(不是 HTTP):
otpauth://totp/Muieay:admin?issuer=Muieay&secret=ELXVKSD53UJAU7EGZ2YIIISZMI
约定字符串格式如下:
++otpauth://totp/[ 客户端显示的账户信息 ]?secret=[secretBase32]++
2、简单代码实现原理,如下
1 2 3 4 5 6 7 QrConfig config = new QrConfig ();String secretBase32 = "cm56gdhcjo1cs8pihg0qbmeudp280isq" ;String qrCode = "otpauth://totp/Hello1:Hello2?issuer=Hello3&secret=" + secretBase32;config.setErrorCorrection(ErrorCorrectionLevel.H); QrCodeUtil.generate(qrCode, config, FileUtil.file("E:\c\qrcodeCustom.jpg" ));
Spring引入MFA 引入依赖 ++java-totp ++ 1 2 3 4 5 <dependency > <groupId > dev.samstevens.totp</groupId > <artifactId > totp</artifactId > <version > 1.7.1</version > </dependency >
生成二维码测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 SecretGenerator secretGenerator = new DefaultSecretGenerator ();String secret = secretGenerator.generate();System.err.println("secret = " + secret); QrData data = new QrData .Builder() .label("example@example.com" ) .secret(secret) .issuer("AppName" ) .algorithm(HashingAlgorithm.SHA1) .digits(6 ) .period(30 ) .build(); QrGenerator generator = new ZxingPngQrGenerator ();byte [] imageData = generator.generate(data);FileUtil.writeBytes(imageData, "E:\static\qrcodeCustom2.jpg" );
验证 MFA 二维码测试 1 2 3 4 5 6 7 8 9 10 11 12 TimeProvider timeProvider = new SystemTimeProvider ();CodeGenerator codeGenerator = new DefaultCodeGenerator ();CodeVerifier verifier = new DefaultCodeVerifier (codeGenerator, timeProvider);String code = "470217" ;String testSecret="QUF7EQA5M7CVJWE6UD5SCPTWKJLAXUMO" ; boolean successful = verifier.isValidCode(testSecret, code);System.err.println("successful = " + successful);
以下是简单的接口实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 @RestController @RequestMapping("/qr") public class QRController { @Resource private QrTestService qrTestService; @GetMapping("/getQr") public ResponseEntity<byte []> getQrCode() throws QrGenerationException { SecretGenerator secretGenerator = new DefaultSecretGenerator (); String secret = secretGenerator.generate(); qrTestService.save(new QrTest (secret)); QrData data = new QrData .Builder() .label("hello@qq.com" ) .secret(secret) .issuer("AppName" ) .algorithm(HashingAlgorithm.SHA1) .digits(6 ) .period(30 ) .build(); QrGenerator generator = new ZxingPngQrGenerator (); byte [] imageData = generator.generate(data); return ResponseEntity.ok() .contentType(MediaType.IMAGE_PNG) .body(imageData); } @GetMapping("/check/{id}/{code}") public String checkCode (@PathVariable Integer id,@PathVariable String code) { TimeProvider timeProvider = new SystemTimeProvider (); CodeGenerator codeGenerator = new DefaultCodeGenerator (); CodeVerifier verifier = new DefaultCodeVerifier (codeGenerator, timeProvider); QrTest qrTest = qrTestService.getById(id); String testSecret = qrTest.getSecret(); boolean successful = verifier.isValidCode(testSecret, code); return successful ? "success" : "fail" ; } }
相关参考链接
https://ruanyifeng.com/blog/2017/11/2fa-tutorial.html
https://www.cnblogs.com/loveyou/p/6989064.html
https://github.com/samdjstevens/java-totp
https://github.com/hectorm/otpauth
https://github.com/suyin58/otp-demo/tree/master