如何在ASP.NET Core站点验证Flutter应用生成的TOTP验证码?
TOTP验证码在Flutter(Dart)和ASP.NET Core(C#)端不一致的问题解决
核心问题:密钥编码方式不统一
你两边的代码对密钥的处理逻辑完全不同,直接导致生成的TOTP验证码不一致:
- Flutter/Dart端:
OTP.generateTOTPCodeString设置isGoogle: false时,会直接将密钥字符串按UTF-8编码转换为字节数组用于计算。 - ASP.NET Core端:你使用了
Base32Encoding.ToBytes(skey),这是将密钥字符串当作Base32编码格式解码为字节数组,和Dart端的处理逻辑完全不匹配。
解决方案:统一密钥处理方式
方案1:统一使用UTF-8编码处理密钥
保持Dart端代码不变,修改C#端代码,改用UTF-8编码获取密钥字节:
string skey = "DDXFM42476476545"; var now = new DateTime(2023, 04, 26, 10, 10, 10); // 使用UTF-8编码获取密钥字节,和Dart端保持一致 var totp = new Totp(Encoding.UTF8.GetBytes(skey), 30, OtpHashMode.Sha256); var code = totp.ComputeTotp(now); // 现在会和Dart端输出一致:667099
方案2:统一使用Base32编码处理密钥
如果希望遵循TOTP通用规范(通常推荐用Base32存储密钥),可以修改两端代码统一用Base32:
- Dart端:设置
isGoogle: true(该库的isGoogle参数为true时,会将密钥当作Base32解码):
var now = DateTime(2023, 04, 26, 10, 10, 10); var code = OTP.generateTOTPCodeString( 'DDXFM42476476545', now.millisecondsSinceEpoch, algorithm: Algorithm.SHA256, isGoogle: true); print(code); // 输出会和C#端原代码一致:734057
- C#端保持原代码不变即可。
额外注意:时间时区一致性
为了避免时区差异导致的时间戳计算偏差,建议两端都使用UTC时间来生成验证码:
- Dart端:
var now = DateTime(2023, 04, 26, 10, 10, 10).toUtc();
- C#端:
var now = new DateTime(2023, 04, 26, 10, 10, 10).ToUniversalTime();
内容的提问来源于stack exchange,提问作者Tareq
相关产品推荐
相关产品推荐

