Last active
January 31, 2021 13:17
-
-
Save neil-sabol/3d48308b57f25da59dd6b28b34d9d42e to your computer and use it in GitHub Desktop.
See https://blog.neilsabol.site/post/yubikey-manager-ykman-powershell-cli-duo-mfa-oath-totp-token/ . This snippet uses the ykman command to generate an OATH-TOTP credential on the Yubikey which can be used with services that require you to supply your own TOTP secret.
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
# Create an alias for ykman pointing the install location | |
set-alias ykman "$env:programfiles\Yubico\YubiKey Manager\ykman.exe" | |
# Get the Yubikey's serial number with ykman | |
# Not required but will be used to import into Duo later (to test) | |
$serialNumber = ykman info | where { $_ -like "Serial number:*" } | | |
%{ $_ -replace "Serial number: ",""} | |
# Generate a random 40 character hex secret | |
# See https://codegolf.stackexchange.com/questions/58442/generate-random-uuid - thanks Forty3 | |
# The length of the hex secret must be divisible by 5 to leverage HumanEquivalentUnit's | |
# byte to base32 conversion code below - I used a 40 digit secret | |
$hexSecret = (((40)|%{((1..$_)|%{('{0:X}' -f (random(16)))})}) -Join "").ToLower() | |
# Convert the hex secret key to base32 (with byte array as an intermediary) | |
# This seemed like the easier path vs. generating a base32 secret and converting back to hex | |
# First, from hex to bytes | |
# See https://gist.github.com/jonfriesen/234c7471c3e3199f97d5 | |
# ( function Convert-HexToByteArray ) - thanks Jon Friesen | |
$byteSecret = $hexSecret -replace '^0x', '' -split "(?<=\G\w{2})(?=\w{2})" | | |
%{ [Convert]::ToByte( $_, 16 ) } | |
# Then, from bytes to base32 | |
# See https://humanequivalentunit.github.io/Base32-coding-the-scripting-way/ | |
# Thanks humanequivalentunit | |
$byteArrayAsBinaryString = -join $byteSecret.ForEach{ | |
[Convert]::ToString($_, 2).PadLeft(8, '0') | |
} | |
$base32Secret = [regex]::Replace($byteArrayAsBinaryString, '.{5}', { | |
param($Match) | |
'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'[[Convert]::ToInt32($Match.Value, 2)] | |
}).ToLower() | |
# Create a new OATH-TOTP credential in the Yubikey for Yubico Authenticator | |
ykman oath add -o TOTP -d 6 -p 30 "DuoTest" "$base32Secret" | |
# Write out the TOTP token info in Duo CSV format | |
# Not required but will be used to import into Duo for testing | |
write-host "$serialNumber,$hexSecret" | |
# Clear variables | |
$serialNumber = "" | |
$hexSecret = "" | |
$byteSecret = "" | |
$base32Secret = "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment