-
-
Save azbesthu/570951cbf05c2c8af142712852ac7997 to your computer and use it in GitHub Desktop.
TOTP Client for PowerShell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#requires -version 2 | |
<# | |
.SYNOPSIS | |
Time-base One-Time Password Algorithm (RFC 6238) | |
.DESCRIPTION | |
This is an implementation of the RFC 6238 Time-Based One-Time Password Algorithm draft based upon the HMAC-based One-Time Password (HOTP) algorithm (RFC 4226). This is a time based variant of the HOTP algorithm providing short-lived OTP values. | |
.NOTES | |
Version: 1.0 | |
Author: Jon Friesen | |
Creation Date: May 7, 2015 | |
Purpose/Change: Provide an easy way of generating OTPs | |
#> | |
function Get-Otp($SECRET, $LENGTH, $WINDOW){ | |
$enc = [System.Text.Encoding]::UTF8 | |
$hmac = New-Object -TypeName System.Security.Cryptography.HMACSHA1 | |
$hmac.key = Convert-HexToByteArray(Convert-Base32ToHex(($SECRET.ToUpper()))) | |
$timeBytes = Get-TimeByteArray $WINDOW | |
$randHash = $hmac.ComputeHash($timeBytes) | |
$offset = $randhash[($randHash.Length-1)] -band 0xf | |
$fullOTP = ($randhash[$offset] -band 0x7f) * [math]::pow(2, 24) | |
$fullOTP += ($randHash[$offset + 1] -band 0xff) * [math]::pow(2, 16) | |
$fullOTP += ($randHash[$offset + 2] -band 0xff) * [math]::pow(2, 8) | |
$fullOTP += ($randHash[$offset + 3] -band 0xff) | |
$modNumber = [math]::pow(10, $LENGTH) | |
$otp = $fullOTP % $modNumber | |
$otp = $otp.ToString("0" * $LENGTH) | |
return $otp | |
} | |
function Get-TimeByteArray($WINDOW) { | |
$span = (New-TimeSpan -Start (Get-Date -Year 1970 -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0) -End (Get-Date).ToUniversalTime()).TotalSeconds | |
$unixTime = [Convert]::ToInt64([Math]::Floor($span/$WINDOW)) | |
$byteArray = [BitConverter]::GetBytes($unixTime) | |
[array]::Reverse($byteArray) | |
return $byteArray | |
} | |
function Convert-HexToByteArray($hexString) { | |
$byteArray = $hexString -replace '^0x', '' -split "(?<=\G\w{2})(?=\w{2})" | %{ [Convert]::ToByte( $_, 16 ) } | |
return $byteArray | |
} | |
function Convert-Base32ToHex($base32) { | |
$base32chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; | |
$bits = ""; | |
$hex = ""; | |
for ($i = 0; $i -lt $base32.Length; $i++) { | |
$val = $base32chars.IndexOf($base32.Chars($i)); | |
$binary = [Convert]::ToString($val, 2) | |
$staticLen = 5 | |
$padder = '0' | |
# Write-Host $binary | |
$bits += Add-LeftPad $binary.ToString() $staticLen $padder | |
} | |
for ($i = 0; $i+4 -le $bits.Length; $i+=4) { | |
$chunk = $bits.Substring($i, 4) | |
# Write-Host $chunk | |
$intChunk = [Convert]::ToInt32($chunk, 2) | |
$hexChunk = Convert-IntToHex($intChunk) | |
# Write-Host $hexChunk | |
$hex = $hex + $hexChunk | |
} | |
return $hex; | |
} | |
function Convert-IntToHex([int]$num) { | |
return ('{0:x}' -f $num) | |
} | |
function Add-LeftPad($str, $len, $pad) { | |
if(($len + 1) -ge $str.Length) { | |
while (($len - 1) -ge $str.Length) { | |
$str = ($pad + $str) | |
} | |
} | |
return $str; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Very basic sketch example. Need powershell 6+ for generating txt without bom.