Flutter一次性密码生成与验证插件otp_util的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter一次性密码生成与验证插件 otp_util 的使用

otp_util 是一个用于生成和验证一次性密码(OTP)的 Dart 包,适用于实现双因素认证(2FA)和多因素认证(MFA)等登录系统。

该包基于 RFC4226RFC6238 实现了 HMAC-Based One-Time Password (HOTP) 和 Time-Based One-Time Password (TOTP) 算法。

功能

  • 创建并验证 HOTP 对象
  • 创建并验证 TOTP 对象
  • 生成带有 Base32 编码字符串的 otpauth url
  • 支持使用 SHA1、SHA256、SHA384 和 SHA512 加密的 OTP 令牌

安装

Pubspec

在项目的 pubspec.yaml 文件中添加 otp_util 依赖:

dependencies:
  otp_util: ^1.0.2

示例代码

时间戳为基础的 OTPs (TOTP)

import 'package:otp_util/otp_util.dart';

void main() {
  // 默认初始化,时间间隔为30秒,生成6位数的令牌
  TOTP totp = TOTP(secret: "BASE32ENCODEDSECRET");

  // 自定义初始化,时间间隔为60秒,生成8位数的令牌
  TOTP totpCustom = TOTP(secret: "BASE32ENCODEDSECRET", interval: 60, digits: 8);

  print(totp.now()); // 输出当前时间的 OTP

  // 验证当前时间的 OTP
  bool isValidNow = totp.verify(otp: '745872');
  print(isValidNow); // true 或 false

  // 验证30秒后的 OTP
  bool isValidAfter30Seconds = totp.verify(otp: '745872', time: DateTime.now().add(Duration(seconds: 30)));
  print(isValidAfter30Seconds); // false
}

计数器为基础的 OTPs (HOTP)

import 'package:otp_util/otp_util.dart';

void main() {
  // 默认初始化,计数器从0开始,生成6位数的令牌
  HOTP hotp = HOTP(secret: "BASE32ENCODEDSECRET");

  // 自定义初始化,计数器从50开始,生成8位数的令牌
  HOTP hotpCustom = HOTP(secret: "BASE32ENCODEDSECRET", counter: 50, digits: 8);

  print(hotp.at(counter: 0)); // 输出计数器为0时的 OTP
  print(hotp.at(counter: 1)); // 输出计数器为1时的 OTP
  print(hotp.at(counter: 2438)); // 输出计数器为2438时的 OTP

  // 验证指定计数器的 OTP
  bool isValidAtCounter2438 = hotp.verify(otp: '397732', counter: 2438);
  print(isValidAtCounter2438); // true 或 false
}

更完整的示例 Demo

以下是一个更完整的示例,展示了如何生成和验证 TOTP 和 HOTP:

import 'package:otp_util/otp_util.dart';
import 'dart:convert';

void main() {
  // TOTP 示例
  TOTP totp = TOTP(secret: base32Encode(utf8.encode("mysecret")));
  print('Current TOTP: ${totp.now()}');
  print('Value at current time: ${totp.value(date: DateTime.now())}');
  print('Verification result: ${totp.verify(otp: totp.now(), time: DateTime.now())}');

  TOTP totpCustom = TOTP(secret: base32Encode(utf8.encode("mysecret")), interval: 60, digits: 8);
  print('Custom TOTP: ${totpCustom.now()}');
  print('Value at custom time: ${totpCustom.value(date: DateTime.parse('2018-10-10 09:30:36'))}');
  print('Verification result: ${totpCustom.verify(otp: '80271722', time: DateTime.parse('2018-10-10 09:30:36'))}');

  print('*******************************');

  // HOTP 示例
  HOTP hotp = HOTP(secret: base32Encode(utf8.encode("mysecret")));
  print('HOTP at counter 0: ${hotp.at(counter: 0)}');
  print('HOTP at counter 1: ${hotp.at(counter: 1)}');
  print('HOTP at counter 2438: ${hotp.at(counter: 2438)}');
  print('Verification result: ${hotp.verify(otp: '397732', counter: 2438)}');

  HOTP hotpCustom = HOTP(secret: base32Encode(utf8.encode("mysecret")), counter: 60, digits: 8);
  print('Custom HOTP at counter 0: ${hotpCustom.at(counter: 0)}');
  print('Custom HOTP at counter 1: ${hotpCustom.at(counter: 1)}');
  print('Custom HOTP at counter 2438: ${hotpCustom.at(counter: 2438)}');
  print('Verification result: ${hotpCustom.verify(otp: '75397732', counter: 2438)}');
}

更多关于Flutter一次性密码生成与验证插件otp_util的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter一次性密码生成与验证插件otp_util的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用otp_util插件来生成和验证一次性密码(OTP)的示例代码。这个插件通常用于实现双重认证(2FA)。

首先,确保你已经在pubspec.yaml文件中添加了otp_util依赖:

dependencies:
  flutter:
    sdk: flutter
  otp_util: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

接下来,我们编写一个Flutter应用,展示如何使用otp_util生成和验证OTP。

主应用代码(main.dart

import 'package:flutter/material.dart';
import 'package:otp_util/otp_util.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final TextEditingController _secretController = TextEditingController();
  final TextEditingController _otpController = TextEditingController();
  String? _generatedOtp;
  bool _isVerified = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('OTP Util Demo'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              TextField(
                controller: _secretController,
                decoration: InputDecoration(
                  labelText: 'Secret Key',
                ),
              ),
              SizedBox(height: 16),
              ElevatedButton(
                onPressed: _generateOtp,
                child: Text('Generate OTP'),
              ),
              SizedBox(height: 16),
              Text(
                _generatedOtp ?? '',
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
              ),
              SizedBox(height: 32),
              TextField(
                controller: _otpController,
                decoration: InputDecoration(
                  labelText: 'Enter OTP',
                ),
              ),
              SizedBox(height: 16),
              ElevatedButton(
                onPressed: _verifyOtp,
                child: Text('Verify OTP'),
                color: _isVerified ? Colors.green : Colors.blue,
              ),
              SizedBox(height: 16),
              Text(
                _isVerified ? 'OTP Verified!' : '',
                style: TextStyle(color: Colors.green, fontSize: 18),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void _generateOtp() {
    final secret = _secretController.text.trim();
    if (secret.isEmpty) {
      return; // Handle empty secret key case
    }

    final otp = OtpUtil.generateTotp(secret: secret);
    setState(() {
      _generatedOtp = otp;
      _otpController.clear();
      _isVerified = false;
    });
  }

  void _verifyOtp() {
    final enteredOtp = _otpController.text.trim();
    final secret = _secretController.text.trim();
    if (secret.isEmpty || enteredOtp.isEmpty) {
      return; // Handle empty fields case
    }

    final isVerified = OtpUtil.verifyTotp(secret: secret, otp: enteredOtp);
    setState(() {
      _isVerified = isVerified;
    });
  }
}

代码解释

  1. 依赖导入

    • 导入otp_util包来处理OTP生成和验证。
  2. UI布局

    • 使用MaterialAppScaffold来创建基本的应用布局。
    • 使用TextField来输入秘密密钥和OTP。
    • 使用ElevatedButton来触发OTP生成和验证操作。
  3. OTP生成

    • 使用OtpUtil.generateTotp(secret: secret)根据提供的秘密密钥生成OTP。
  4. OTP验证

    • 使用OtpUtil.verifyTotp(secret: secret, otp: enteredOtp)来验证用户输入的OTP是否正确。
  5. 状态管理

    • 使用setState来更新UI状态,例如生成的OTP、OTP验证结果等。

这个示例展示了如何使用otp_util插件在Flutter应用中实现OTP的生成和验证。你可以根据需求进一步扩展和定制这个示例。

回到顶部