Ability to set and retrieve OTP via API.APIOct 5, 2020Ability to set and retrieve OTP via API, both results and key.1 comment76
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')}