1

我正在尝试生成 TOTP,以便我可以使用 Google Authenticator 应用程序。我正在使用cryptonite提供 TOTP 功能的库。

据我了解,Google Authenticator 需要 Base32 中的密钥。它还需要=删除填充。Cryptonite 提供了一个unpad函数,但我并不真正理解它是如何工作的,因此无法弄清楚第一个参数应该是什么,我尝试过的所有内容都会使函数 return Nothing

出于测试目的,我选择了一个没有填充的密钥,但是,我的程序生成的代码与 Google Authenticator 生成的代码不匹配。

代码产生的Base32密钥如下:

GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ

将其输入 Google Authenticator 不会产生与我的代码产生的结果相同的结果。

这是我的代码:

{-# LANGUAGE OverloadedStrings #-}

module TOTP
    ( genTOTP
    ) where

import qualified Basement.Imports        as Base (String)
import           Crypto.Data.Padding
import           Crypto.OTP              (defaultTOTPParams, totp)
import           Data.ByteArray
import           Data.ByteArray.Encoding
import           Data.Time.Clock.POSIX

genTOTP :: IO ()
genTOTP = do
    time <- getPOSIXTime
    let secret = "12345678901234567890" :: Base.String
        keyBytes = convertToBase Base32 secret :: Bytes
        key = keyBytes -- unpad (PKCS7 6) keyBytes -- I don't know what the first argument to unpad should be
        code = totp defaultTOTPParams key (round time)
    print code

总之,我不确定如何=从密钥中取消填充字节。其次,当使用没有填充的键进行测试时,我仍然没有得到正确的结果。

编辑:如果它对任何人有帮助,我确实设法在没有使用的情况下在 Haskell 中找到了某人的 Google Authenticator 实现,cryptonite但是我仍然无法弄清楚为什么我的代码不起作用。 Haskell 中的 Google 身份验证器

4

1 回答 1

0

我在以下与 Python 中的实现相关的问题中找到了我的问题的答案,here

在将其输入 Google Authenticator 之前将其转换为 base32 是正确的secret,但我不知道 Google Authenticator 在生成代码之前将其从 base32 转换回常规密钥。

如果我只是要求totp输入secretGoogle keyBytesAuthenticator,我会得到匹配的代码。

于 2018-05-26T15:43:18.843 回答