Android Question Unable to integrate with Google Authenticator app

toby

Well-Known Member
Licensed User
Longtime User
The problem: my app fails to produce an identical TOTP as the one produced by Google Authenticator app when same secret key is used. Could someone tell me what went wrong, please. My focus is TOTP verification not secret key generation.

TIA
authenticator integration class:
Sub Class_Globals

End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize

End Sub



Sub VerifyTOTP(secretKey As String, userEnteredCode As String) As Boolean
    Dim currentTimeSlice As Long = Floor(DateTime.Now / 30000) ' 30 seconds time slice
    
    For i = -1 To 1 ' Check previous, current, and next time slices
        Dim timeSlice As Long = currentTimeSlice + i
        Dim expectedCode As String = GenerateTOTP(secretKey, timeSlice)
        If expectedCode = userEnteredCode Then
            Return True
        End If
    Next
    
    Return False
End Sub

Sub GenerateTOTP(secretKey As String, timeSlice As Long) As String
   ' Dim keyBytes() As Byte = Base32Decode(secretKey) ' Decode Base32 secret to bytes
    Dim timeSliceBytes() As Byte = LongToBytes(timeSlice)
    
    Dim hmacBytes() As Byte = hmac_SHA1(timeSliceBytes, secretKey)
    Dim offset As Int = Bit.And(hmacBytes(hmacBytes.Length - 1), 0xF)
    
    Dim code As Long = Bit.And(hmacBytes(offset), 0x7F)
    code = Bit.Or(Bit.ShiftLeft(code, 8), Bit.And(hmacBytes(offset + 1), 0xFF))
    code = Bit.Or(Bit.ShiftLeft(code, 8), Bit.And(hmacBytes(offset + 2), 0xFF))
    code = Bit.Or(Bit.ShiftLeft(code, 8), Bit.And(hmacBytes(offset + 3), 0xFF))
    code = code Mod 1000000 ' 6-digit code
    
    Return NumberFormat(code, 6, 0)
End Sub

Sub hmac_SHA1(data() As Byte, key As String) As Byte()
    Try
        Dim m As Mac
        Dim k As KeyGenerator
        k.Initialize("HMACSHA1")
        
        ' Corrected: Convert the key to raw bytes based on its Base32 encoding
        Dim keyBytes() As Byte = Base32Decode(key)
        k.KeyFromBytes(keyBytes)
        
        m.Initialise("HMACSHA1", k.Key)
        m.Update(data)
        
        Dim b() As Byte = m.Sign
        Return b
    Catch
        Log("Error in hmac_SHA1: " & LastException.Message)
        Return Null
    End Try
End Sub

Sub LongToBytes(value As Long) As Byte()
    Dim bytes(8) As Byte ' A long value has 8 bytes
    For i = 0 To 7
        bytes(7 - i) = Bit.And(Bit.ShiftRight(value, i * 8), 0xFF)
    Next
    Return bytes
End Sub


Sub Base32Decode(encoded As String) As Byte()
    Dim Base32Chars As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
    Dim bits As Int = 0
    Dim value As Long = 0
    Dim buffer As List
    buffer.Initialize
    For i = 0 To encoded.Length - 1
        value = Bit.Or(Bit.ShiftLeft(value, 5), Base32Chars.IndexOf(encoded.CharAt(i)))
        bits = bits + 5
        If bits >= 8 Then
            buffer.Add(Bit.And(Bit.ShiftRight(value, bits - 8), 0xFF))
            bits = bits - 8
        End If
    Next
    
    ' Convert the list of bytes to a byte array
    Dim byteArray(buffer.Size) As Byte
    For i = 0 To buffer.Size - 1
        byteArray(i) = buffer.Get(i)
    Next
    Return byteArray
End Sub

test code:
#Region Shared Files
#CustomBuildAction: folders ready, %WINDIR%\System32\Robocopy.exe,"..\..\Shared Files" "..\Files"
'Ctrl + click to sync files: ide://run?file=%WINDIR%\System32\Robocopy.exe&args=..\..\Shared+Files&args=..\Files&FilesSync=True
#End Region

'Ctrl + click to export as zip: ide://run?File=%B4X%\Zipper.jar&Args=GoogleAuthenticatorIntegration.zip

Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Dim googleAuthenticator As clsGoogleAuthenticator
    Private imvQrCode As ImageView
    Private secretKey As String="KGJ3U23QMMXDLFOF" 'hard coded secret key for testing, 16 alphanumeric chars
    Private B4XFloatTextField1 As B4XFloatTextField
End Sub

Public Sub Initialize
'    B4XPages.GetManager.LogEvents = True
    googleAuthenticator.Initialize

End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
End Sub

'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.

Private Sub Button1_Click
    'xui.MsgboxAsync("Hello world!", "B4X")
    secretKey=googleAuthenticator.GenerateSecretKey
    'secretKey="KGJ3U23QMMXDLFOF" 'hard coded secret key for testing


End Sub




Private Sub btnVerify_Click
    Dim userCode As String=B4XFloatTextField1.Text.Trim
    If googleAuthenticator.VerifyTOTP(secretKey, userCode) Then
        Log("Verified")
    Else
        Log("Failed")
    End If
End Sub
 

Attachments

  • GoogleAuthenticatorIntegration.zip
    16.6 KB · Views: 57
Top