如何计算R中的Google身份验证器TOTP号码?

问题描述 投票:0回答:1

我想在闪亮的应用程序中添加两因素身份验证,所以我一直在尝试在R中使用TOTP的Google身份验证器实现。我可以创建一个六位数的数字,但我的数字与应用。我最好的猜测是SHA1没有正确执行,在这里我使用时间键进行哈希,然后将该哈希用作第二个哈希的密钥。或者,也许我没有得到较低的半字节或符号位掩码?

谁能看到我要去哪里了吗?

我正在使用此网站作为指南,包括指向他的Go代码的链接:https://garbagecollected.org/2014/09/14/how-google-authenticator-works/

我也尝试过digest::digest(x, algo="sha1", serialize=FALSE),但是它不允许我指定键,所以我不知道它是否可以工作。

library(qrcode)
library(openssl)
library(base64url)

secret <- "supersecret"
secret32 <- base64url::base32_encode(secret)
secretmsg <- paste0("otpauth://totp/R%20Authenticator%20test?secret=", secret32, "&issuer=test")
qrcode::qrcode_gen(secretmsg)

# use math to convert from raw to integer, allow for lower nibble and unsign
rawToInt <- function(x, part=NULL) {
    logivect <- as.logical(rawToBits(x))
    if(length(part)) {
        if(part == "l") logivect <- logivect[1:4] # lower nibble
        else if(part == "m") logivect[length(logivect)] <- FALSE # mask most sig. bit
    }
    sum(2^(which(logivect)-1))
} 

# Generate a six-digit number
authenticator <- function(secret) {
    # Unix time
    n <- as.numeric(Sys.time())
    # The hash
    hmac <- openssl::sha1(secret, key=openssl::sha1(secret, key=intToBits(n/30)))
    # Convert hash to raw
    hmac_raw <- charToRaw(hmac)
    # Take the last byte (nibble)
    last_byte <- hmac_raw[(length(hmac_raw)-1):length(hmac_raw)]
    # Use only the first 4 bits (lower nibble), R puts least sig bits at left
    offset <- rawToInt(last_byte, part='l')
    # multiply by 2 because R reports each byte as 2 hex chars, 
    # add 1 because R indexes from 1
    offset <- (offset*2+1):(offset*2+8)
    four_bytes <- hmac_raw[offset]
    # Ignore most sig. bit
    large_integer <- rawToInt(four_bytes, part='m')
    small_integer <- large_integer %% 1e6
    # Make it print pretty
    nc <- nchar(small_integer)
    small_int_print <- paste0(rep(0, 6-nc), format(small_integer, big.mark=" "))
    # Time remaining
    remain <- round(30-n%%30)
    cat(
        remain, "seconds remaining\n",
        small_int_print, "\n"
    )
    invisible(small_integer)
}

authenticator(secret=secret)
r two-factor-authentication google-authenticator
1个回答
0
投票

您是否已确认生成6位数字代码的服务器和运行该应用程序的电话上的时间是同步的?确保在登台服务器上设置NTP并同步时间,并可能在手机上的Google Authenticator应用中同步时间。

从Google的文档:

默认情况下,令牌有效期为30秒,以补偿对于客户端和服务器之间可能的时间偏差,我们允许当前时间之前和之后的额外令牌。如果你有经验时间同步不良的问题,您可以增加窗口从其默认大小1:30min到大约4min。

将分钟和秒与某些站点链接进行比较:https://www.timeanddate.com/

在Android / iOS Google Authenticator应用上同步时间:

https://support.google.com/accounts/answer/185834?hl=en

滚动到最底部:“我的Google身份验证器代码不起作用(Android)”

© www.soinside.com 2019 - 2024. All rights reserved.