使用具有经典 ASP 的 2FA 身份验证总是 returns 无效响应

Using 2FA authentication with classic ASP always returns an invalid response

我正在使用来自 GitHub

的代码

https://github.com/as08/ClassicASP.TwoFactorAuthentication

我下载了演示站点,在服务器上安装了我需要的东西,一切正常。演示站点有很多代码,所以我将其分解为 Github 页面上显示的两个部分 1) 生成密钥和 QR 码 2) 验证验证码。

我制作了 2 个非常准系统的基本 asp 页

index.asp

<%
Dim TwoFA : Set TwoFA = Server.CreateObject("ClassicASP.TwoFactorAuthentication")
    
    TwoFA.SecretKeyLength(20)
    TwoFA.HashMode("SHA1")
    TwoFA.totpSize(6)
  RecoveryPasswordLength = 18
  
    Dim SecretKey, RecoveryPassword, GenerateQR
                    
    SecretKey = TwoFA.GenerateSecretKey()
    RecoveryPassword = TwoFA.RecoveryPassword(RecoveryPasswordLength)
  
  response.write("Secret Key: " & secretKey & "<br>")
  response.write("Recovery Password: " & RecoveryPassword & "<br />")
  
    ' Generate the QR code

    GenerateQR = "<img src=""https://chart.googleapis.com/chart" &_
    "?chs=320x320" &_
    "&chld=H|0" &_
    "&cht=qr" &_
    "&chl=" & Server.URLencode("otpauth://totp/test@test.com" &_ 
    "?secret=" & SecretKey &_ 
    "&issuer=examplesite.com" &_ 
    "&algorithm=SHA1" &_ 
    "&digits=6" &_ 
    "&period=30") & "&choe=UTF-8"" " &_
  "class=""img-fluid border-info border mt-4 QRframe"" " &_  
    "width=""320px"" height=""320px"">"

Set TwoFA = Nothing
%>
<%=GenerateQR%>

Validate.asp

<%
Dim TwoFA : Set TwoFA = Server.CreateObject("ClassicASP.TwoFactorAuthentication")

    TwoFA.SecretKeyLength(20)
    TwoFA.HashMode("SHA1")
    TwoFA.totpSize(6)
  TOTP = request("totp")
  
  response.write(totp & "<br />")

    If TwoFA.Verify("EDSLKFQENTEFPATYN5LAZ5BCGD2UOR4R",cStr(TOTP)) Then

        ' Valid Time-based One-time Password (TOTP)
    response.write("valid")

    Else

        ' Invalid TOTP
    response.write("invalid")

    End If

Set TwoFA = Nothing
%>

为了测试,我转到了我的 index.asp 页面并生成了一个二维码并在 Microsoft Authenticator 中进行了设置。然后,我获取了密钥并将其硬编码到验证页面的验证调用中。然后我进入 Authenticator 并获取代码并通过转到 validate.asp?totp=123456 对其进行测试。无论我做什么,我都无法让它发挥作用。我总是得到 response.write("invalid") 结果。

为什么即使我使用正确的密钥输入正确的 6 位代码也没有返回有效响应?

我想通了。我希望这对将来的人有帮助。不幸的是,在文档中,它在 cStr(TOTP) 中包含 TOTP,从而将其转换为字符串......但我删除了 cStr() 并且在请求中我通过执行以下操作将其强制为整数:

TOTP = request("totp")+0

现在可以了!

这不是一个答案,但它太长太详细,无法作为评论留下。

我已经从我的 GitHub 存储库下载并 运行 演示,并使用了 Microsoft 身份验证器、Google 身份验证器和 Authy。它们都工作正常,包括 30 秒 tole运行ce。我什至将我的时区更改为各种不同的时区(尽管这不能解释您描述的 4 秒到期时间,但他们没有。我只是涵盖了我的所有基地)。

我只能推荐这个,下载并 运行 这个 UTC.asp 页面:

<%=UTC_DateTime()%>
<script language="JScript" runat="server">
    
    // Return the current UTC date and time regardless of what timezone the server is set to
    
    function UTC_DateTime() {
        
        var date = new Date();
        
        // date.getUTCMonth() returns a value from 0 - 11 (?) so we need to  + 1
        
        var result = date.getUTCFullYear() + "-" + (date.getUTCMonth() + 1) + "-" + date.getUTCDate() + " " + date.getUTCHours() + ":" + date.getUTCMinutes() + ":" + date.getUTCSeconds();
        
        // Pad month/day/hour/minute/second values with a 0 if necessary
        
        return result.replace(/(\D)(\d)(?!\d)/g, "");
        
    }

</script>

然后将其与 timeanddate.com 之类的网站进行比较,如果时间不相同(给定或花费几秒钟),则说明您的服务器时间设置有问题,它必须生成不同步的 UTC 时间。某种 NTP 故障?

如果是这样的话,我没有答案,希望有人能回答,但这一定是问题所在,因为它对我来说工作正常。 (我 运行 iOS 上的所有应用程序以及 Windows 10 和 Windows Server 2016 上的演示只是为了澄清)