Skip to content

Commit d78ab7c

Browse files
authored
Display in hex via helper class. (#162)
* Display in hex via helper class.
1 parent 60370c6 commit d78ab7c

3 files changed

Lines changed: 78 additions & 4 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,4 +362,5 @@ MigrationBackup/
362362
# Fody - auto-generated XML schema
363363
FodyWeavers.xsd
364364
/.vscode/launch.json
365-
/powershellYK.psd1
365+
/powershellYK.psd1
366+
/.cursorrules

Module/Cmdlets/OTP/SetYubikeyOTP.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
/// Set-YubiKeyOTP -Slot ShortPress -HOTP -Base32Secret "QRFJ7DTIVASL3PNYXWFIQAQN5RKUJD4U" -AppendCarriageReturn
4747
///
4848
/// .EXAMPLE
49+
/// # Configure HOTP with hex encoded secret and carriage return
50+
/// Set-YubiKeyOTP -Slot ShortPress -HOTP -HexSecret "0102030405060708090a0b0c0d0e0f1011121314" -AppendCarriageReturn
51+
///
52+
/// .EXAMPLE
4953
/// # Configure HOTP with TAB before OTP code for easier form navigation
5054
/// Set-YubiKeyOTP -Slot ShortPress -HOTP -Base32Secret "QRFJ7DTIVASL3PNYXWFIQAQN5RKUJD4U" -SendTabFirst
5155
///
@@ -158,6 +162,10 @@ public class SetYubikeyOTPCommand : PSCmdlet
158162
[Parameter(Mandatory = false, ValueFromPipeline = false, HelpMessage = "Base32 encoded secret key for HOTP", ParameterSetName = "HOTP")]
159163
public string? Base32Secret { get; set; }
160164

165+
// Hex encoded secret key for HOTP mode
166+
[Parameter(Mandatory = false, ValueFromPipeline = false, HelpMessage = "Hex encoded secret key for HOTP", ParameterSetName = "HOTP")]
167+
public string? HexSecret { get; set; }
168+
161169
// Use 8 digits instead of 6 for HOTP mode
162170
[Parameter(Mandatory = false, ValueFromPipeline = false, HelpMessage = "Use 8 digits instead of 6 for HOTP", ParameterSetName = "HOTP")]
163171
public SwitchParameter Use8Digits { get; set; }
@@ -326,12 +334,18 @@ protected override void ProcessRecord()
326334
Memory<byte> _HOTPsecretKey = new Memory<byte>(new byte[20]);
327335
ConfigureHotp configureHOTP = otpSession.ConfigureHotp(Slot);
328336

329-
// Handle Secret Key configuration
337+
// Handle Secret Key configuration using Base32
330338
if (Base32Secret != null)
331339
{
332340
_HOTPsecretKey = powershellYK.support.Base32.Decode(Base32Secret);
333341
configureHOTP = configureHOTP.UseKey(_HOTPsecretKey);
334342
}
343+
// Handle Secret Key configuration using Hex
344+
else if (HexSecret != null)
345+
{
346+
_HOTPsecretKey = powershellYK.support.Hex.Decode(HexSecret);
347+
configureHOTP = configureHOTP.UseKey(_HOTPsecretKey);
348+
}
335349
else if (SecretKey is null)
336350
{
337351
configureHOTP = configureHOTP.GenerateKey(_HOTPsecretKey);
@@ -362,10 +376,10 @@ protected override void ProcessRecord()
362376

363377
configureHOTP.Execute();
364378

365-
// Return both raw and Base32 representations of the key
379+
// Return both Hex and Base32 representations of the key
366380
WriteObject(new
367381
{
368-
SecretKey = _HOTPsecretKey.ToArray(),
382+
HexSecret = powershellYK.support.Hex.Encode(_HOTPsecretKey.ToArray()),
369383
Base32Secret = powershellYK.support.Base32.Encode(_HOTPsecretKey.ToArray())
370384
});
371385
break;

Module/support/Hex.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/// <summary>
2+
/// Utility class for hex encoding and decoding.
3+
/// Provides methods to convert between byte arrays and hex strings.
4+
///
5+
/// .EXAMPLE
6+
/// # Encode a byte array to hex
7+
/// $bytes = [byte[]]@(1,2,3,4,5)
8+
/// $hex = [powershellYK.support.Hex]::Encode($bytes)
9+
///
10+
/// .EXAMPLE
11+
/// # Decode a hex string to bytes
12+
/// $hex = "0102030405"
13+
/// $bytes = [powershellYK.support.Hex]::Decode($hex)
14+
/// </summary>
15+
16+
using System;
17+
using System.Linq;
18+
19+
namespace powershellYK.support
20+
{
21+
public static class Hex
22+
{
23+
// Encodes a byte array to a hex string
24+
public static string Encode(byte[] data)
25+
{
26+
if (data == null)
27+
throw new ArgumentNullException(nameof(data));
28+
29+
if (data.Length == 0)
30+
return string.Empty;
31+
32+
return string.Concat(data.Select(b => b.ToString("x2")));
33+
}
34+
35+
// Decodes a hex string to a byte array
36+
public static byte[] Decode(string hexString)
37+
{
38+
if (string.IsNullOrEmpty(hexString))
39+
return Array.Empty<byte>();
40+
41+
// Remove any whitespace and convert to lowercase
42+
hexString = hexString.Replace(" ", "").ToLower();
43+
44+
// Ensure the string has an even length
45+
if (hexString.Length % 2 != 0)
46+
throw new ArgumentException("Hex string must have an even length");
47+
48+
// Convert each pair of hex characters to a byte
49+
byte[] result = new byte[hexString.Length / 2];
50+
for (int i = 0; i < result.Length; i++)
51+
{
52+
string hexPair = hexString.Substring(i * 2, 2);
53+
result[i] = Convert.ToByte(hexPair, 16);
54+
}
55+
56+
return result;
57+
}
58+
}
59+
}

0 commit comments

Comments
 (0)