Skip to main content

Ability to set and retrieve OTP via API.

Ability to set and retrieve OTP via API, both results and key.

1 comment

Log in to comment and vote

Comments1

  • Red Handle

    •

    May 6

    You can set OTP code via API currently

    And cryptographically speaking, the OTP secret holds all the information you need (so long as your clock is accurate.)

    For our powershell projects that do this, I reuse this snippet all the time- this is a good validator for OTP codes when adding them via API:

    https://github.com/Hudu-Technologies-Inc/Hudu-PassPortal-Migration/blob/49b153f1ed6bc4843023cef989216f6b390c5158/jobs/transfer-passwords.ps1#L40

    This is sufficient for getting your deterministic OTP based on the OTP secret:

    function Get-TotpCode {

    param(    [Parameter(Mandatory)]    [string]$Secret,    [int]$Digits = 6,    [int]$StepSeconds = 30)$base32 = $Secret.ToUpper() -replace '\s','' -replace '=',''$alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"$bits = ""foreach ($char in $base32.ToCharArray()) {    $val = $alphabet.IndexOf($char)    if ($val -lt 0) { throw "Invalid Base32 character: $char" }    $bits += [Convert]::ToString($val, 2).PadLeft(5, '0')}$bytes = for ($i = 0; $i + 8 -le $bits.Length; $i += 8) {    [Convert]::ToByte($bits.Substring($i, 8), 2)}$unixTime = [DateTimeOffset]::UtcNow.ToUnixTimeSeconds()$counter = [Math]::Floor($unixTime / $StepSeconds)$counterBytes = [BitConverter]::GetBytes([Int64]$counter)if ([BitConverter]::IsLittleEndian) { [Array]::Reverse($counterBytes) }$hmac = [System.Security.Cryptography.HMACSHA1]::new([byte[]]$bytes)$hash = $hmac.ComputeHash($counterBytes)$offset = $hash[-1] -band 0x0F$binary =    (($hash[$offset] -band 0x7F) -shl 24) -bor    (($hash[$offset + 1] -band 0xFF) -shl 16) -bor    (($hash[$offset + 2] -band 0xFF) -shl 8) -bor    ($hash[$offset + 3] -band 0xFF)$otp = $binary % [Math]::Pow(10, $Digits)return $otp.ToString().PadLeft($Digits, '0')

    }