Android 2FA原始代码示例

前言:2FA的特点

个人理解:1、不用担心用户验证码的外泄,因为验证码每30s都会改变。2、获取验证码非常的简单,有很多工具。3、无需网络请求,直接本地就可以校验。4、最重要的是,你需要确保2FA的secret(相当于密钥)的安全,不能让外人知道。

1、强化账户安全:2FA提供了额外的安全层,使攻击者更难以入侵用户账户。即使攻击者获得了用户的密码,仍然需要第二个因素才能成功登录。
2、双重身份验证:2FA要求用户提供两个不同的身份验证因素,通常是"知道"、"拥有"和"是"这三个类别中的两个。常见的因素包括密码、手机验证码、指纹、面部识别等。
3、防止密码泄露:2FA提供了一种方式来应对密码泄露的风险。即使密码被泄露,攻击者仍然需要第二个因素才能成功登录。
4、动态密码生成:2FA通常使用动态密码生成器来生成一次性密码。这种密码在一段时间后会过期,增加了安全性。
5、灵活性和可定制性:2FA可以根据不同的需求进行定制。可以选择不同的身份验证因素,设置验证因素的顺序,并根据需要调整验证的强度。
6、广泛支持:2FA已经得到广泛支持,并在许多平台和服务中得到应用,包括社交媒体、电子邮件服务、银行和金融机构等。

1、Android使用的语言:Java

2、导入库

因为一些原因,使用 Base32 解码密钥时,少部分工具,你可能使用错误,造成最后的验证码错误

implementation 'commons-codec:commons-codec:1.15'

注意:可以使用自己原有的解码工具,只要可以生成正确的验证码就行

3、验证码校验类

import org.apache.commons.codec.binary.Base32;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class TwoFactorAuthenticator {
    private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
    private static final int DIGITS = 6;
    private static final int TIME_STEP_SECONDS = 30;

    public static boolean validateTwoFactorCode(String secretKey, String code) {
        long timeStep = System.currentTimeMillis() / 1000 / TIME_STEP_SECONDS; // 当前时间戳除以时间步长(30秒)

        long counter = timeStep;
        String generatedCode = generateCode(secretKey, counter);
        System.out.println("Bin Password->code->" + code);
        System.out.println("Bin Password->generatedCode->" + generatedCode);
        if (generatedCode.equals(code)) {
            return true;
        }

        return false;
    }

    private static String generateCode(String secretKey, long counter) {
        byte[] keyBytes = new Base32().decode(secretKey);
        byte[] counterBytes = longToBytes(counter);

        try {
            SecretKeySpec signingKey = new SecretKeySpec(keyBytes, HMAC_SHA1_ALGORITHM);
            Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
            mac.init(signingKey);
            byte[] hash = mac.doFinal(counterBytes);

            int offset = hash[hash.length - 1] & 0xF;
            int truncatedHash = hashToInt(hash, offset) & 0x7FFFFFFF;
            int pinValue = truncatedHash % (int) Math.pow(10, DIGITS);

            return String.format("%0" + DIGITS + "d", pinValue);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
        }

        return null;
    }

    private static byte[] longToBytes(long value) {
        byte[] result = new byte[8];
        for (int i = 7; i >= 0; i--) {
            result[i] = (byte) (value & 0xFF);
            value >>= 8;
        }
        return result;
    }

    private static int hashToInt(byte[] bytes, int offset) {
        int value = 0;
        for (int i = offset; i < offset + 4; i++) {
            value <<= 8;
            value |= bytes[i] & 0xFF;
        }
        return value;
    }
}

4、使用示例

Boolean result = TwoFactorAuthenticator.validateTwoFactorCode(GLOBAL_PASSWORD_KEY,password);

GLOBAL_PASSWORD_KEY:二次验证码的secret(相当于加密密钥)
password:用户输入的密码
result:验证返回的结果,如果正确,返回true,反正,返回false

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值