简体   繁体   English

如何计算 R 中的谷歌身份验证器 TOTP 编号?

[英]How to compute google authenticator TOTP number in R?

I would like to add two-factor authentication to a shiny application, so I've been trying to work out the google authenticator implementation of TOTP in R.我想向 shiny 应用程序添加两因素身份验证,所以我一直在尝试在 R 中解决 TOTP 的谷歌身份验证器实现。 I can create a six-digit number, but mine doesn't match the app's.我可以创建一个六位数的号码,但我的号码与应用程序的不匹配。 My best guess is that the SHA1 is not being executed properly, where I hash using the time-key and then use that hash as the key for a second hash.我最好的猜测是 SHA1 没有正确执行,我使用时间密钥 hash 然后使用 hash 作为第二个 Z0800FC577294C34E0B28AD283943594 的密钥Or maybe I'm not getting the lower nibble or sign-bit mask right?或者也许我没有得到较低的半字节或符号位掩码?

Can anyone see where I'm going wrong?谁能看到我哪里出错了?

I'm using this site as a guide, including the link to his Go code: https://garbagecollected.org/2014/09/14/how-google-authenticator-works/我使用此站点作为指南,包括指向他的 Go 代码的链接: https://garbagecollected.org/2014/09/14/how-google-authenticator-works/

I've also tried digest::digest(x, algo="sha1", serialize=FALSE) , but it doesn't let me specify a key so I don't know if that can work.我也尝试过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, bits=FALSE) {
    if(!bits) x <- rawToBits(x)
    logivect <- as.logical(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=format(n%/%30)))
    # Convert hash to raw
    hmac_raw <- charToRaw(hmac)
    # Take the last byte
    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]
    # Convert to int
    large_integer <- readBin(four_bytes, integer(), size=4)
    # Mask most sig. bit
    large_integer <- intToBits(large_integer)
    large_integer[length(large_integer)] <- as.raw(0)
    large_integer <- rawToInt(large_integer, bits=TRUE)
    small_integer <- large_integer %% 1e6
    # Make it print pretty
    nc <- nchar(small_integer)
    small_int_print <- paste0(paste0(rep(0, 6-nc), collapse=""), 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)

Have you confirmed that the time is in sync on the server you are generating the 6 Digit Code and the Phone you are running the app on?您是否确认生成 6 位代码的服务器和运行应用程序的电话上的时间同步? Make sure to set up NTP op the Staging Server and sync the Time as well as possibly sync the Time in the Google Authenticator app on your phone.确保在 Staging Server 上设置 NTP 并同步时间,并可能在手机上的 Google Authenticator 应用程序中同步时间。

From Google`s Docs:来自谷歌的文档:

By default, tokens are good for 30 seconds and in order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time.默认情况下,令牌的有效期为 30 秒,为了补偿客户端和服务器之间可能存在的时间偏差,我们允许在当前时间之前和之后使用额外的令牌。 If you experience problems with poor time synchronization, you can increase the window from its default size of 1:30min to about 4min.如果您遇到时间同步不佳的问题,您可以将 window 从其默认大小 1:30 分钟增加到大约 4 分钟。

Compare the minutes and seconds with some site links this: https://www.timeanddate.com/将分钟和秒与一些站点链接进行比较: https://www.timeanddate.com/

Sync time on Android / iOS Google Authenticator App: Android / iOS Google Authenticator App上的同步时间:

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

Scroll to the very bottom section: "My Google Authenticator codes aren't working (Android)"滚动到最底部:“我的 Google 身份验证器代码不起作用(Android)”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM