flutter - Flutter:如何同步 TOTP 代码?
问题描述
我正在编写一个非常简单的 2FA 应用程序,它为给定的密钥、数字、间隔和算法生成 TOTP 代码。
但是,我对数学有困难,我不知道如何构造生成 TOTP 代码的算法
我正在使用 Flutter BLoC 库以 BLoC 模式编写整个应用程序。
看看这个视频,应用程序会生成一个间隔为 30 秒的代码,但是进度指示器不是从 0 秒开始,而是从每 30 秒的一个时间开始,例如:13:00:00 和当 30 秒过去 (13:00:30) 时,它会生成另一个代码。
视频:https ://streamable.com/u7vhcg
现在,当涉及到我的应用程序时,它会生成代码,但它们没有同步。我该怎么做,它会生成代码,但每个代码都是同步的?
我的应用程序视频:https ://streamable.com/zn3pnf
如您所见,TOTP 代码未同步。我该怎么做才能同步它们?
如果您想查看更多代码,请告诉我。
代码
totp_generator_bloc.dart
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:dart_otp/dart_otp.dart';
import 'package:duckie/models/code/code_model.dart';
import 'package:hive/hive.dart';
import 'package:meta/meta.dart';
part 'totp_generator_event.dart';
part 'totp_generator_state.dart';
class TotpGeneratorBloc extends Bloc<TotpGeneratorEvent, TotpGeneratorState> {
TotpGeneratorBloc() : super(TotpGeneratorInitial());
@override
Stream<TotpGeneratorState> mapEventToState(
TotpGeneratorEvent event,
) async* {
if (event is GetTotpItemsEvent) {
Box box = Hive.box('totpmodel');
List totpItems = [];
for (var totpItem in box.values) {
final String secret = totpItem.secret;
final int digits = int.parse(totpItem.digits);
final int interval = int.parse(totpItem.interval);
final String algorithmString = totpItem.algorithm;
final String accountName = totpItem.accountName;
int timeStamp = totpItem.timeStamp;
OTPAlgorithm algorithm = OTPAlgorithm.SHA1;
switch (algorithmString) {
case 'sha1':
algorithm = OTPAlgorithm.SHA1;
break;
case 'sha256':
algorithm = OTPAlgorithm.SHA256;
break;
case 'sha384':
algorithm = OTPAlgorithm.SHA384;
break;
case 'sha512':
algorithm = OTPAlgorithm.SHA512;
break;
}
final TOTP totp = TOTP(
secret: secret,
digits: digits,
interval: interval,
algorithm: algorithm,
);
try {
final String otp =
totp.value(date: DateTime.fromMillisecondsSinceEpoch(timeStamp));
totpItems.add(CodeModel(otp, interval, 0, accountName));
yield TotpGeneratorFinal(totpItems);
} catch (error) {
yield TotpGeneratorError('totp-fail-title', 'totp-fail-content');
}
}
}
}
}
解决方案
这不是订阅 Timer.periodic 的问题吗?
你所在集团之外的东西应该:
从系统时钟(日期时间)读取当前秒数(您将拥有计数器的起始位置)
订阅 Timer.periodic(Duration(seconds: 1), (Timer t) => _handleClocksTick());
_handleClocksTick() - 检查递增的计数器是否可以被 30 整除?
3.1。如果是,则 _bloc.add(GetNewCodeEvent); 重置(计数器);
嗯...我认为您的柜台应该由您的集团处理。这将是更好的解决方案。
像这种情况下的第一个解决方案在颤动上显示运行时钟
推荐阅读
- mysql - 如何在 MySQL 的“EXECUTE STATEMENT USING”语句中使用变量列表?
- python - 为什么要重新初始化多进程工作者?
- android-room - 构建错误:找不到字段的吸气剂
- android - 我在 Android 10 中收到 IMEI 号码错误
- mybatis - Mybatis Interceptor为什么会得到重复的参数
- gitlab - Testcomplete 会支持 GitLab 进行版本控制吗?
- javascript - 我对使用 React JS 和 Virtual DOM 处理重新渲染感到困惑
- python - 在 python 中调用生成器时引发未解决的引用错误
- c - 使用 memcpy 将一维数组复制到一行二维数组
- c# - 为 .net C# 加载 Treeview 的异步方法调用