Public/New-SecretSharingPassword.ps1
|
function New-SecretSharingPassword { <# .SYNOPSIS Generates a random, typeable password at a given entropy level. .DESCRIPTION Returns a cryptographically random password as a SecureString, built with the same one-byte-per-character convention as New-SecretSharingSecret's output, so it can be split and reconstructed via Split-/Join-SecretSharingSecret exactly like any other secret - the value recovered from a quorum of shares is the literal original password, not a derived value. Unlike New-SecretSharingSecret's raw random bytes (values 0-255, not meant to be typed, displayed, or used outside this module), this password is built only from characters that are safe to type, paste, or store in a shell command, URL, CSV file, JSON document, or SQL statement without extra escaping - see Get-SecretSharingPasswordConstant for the exact alphabet and the reasoning behind each excluded character. Because that alphabet carries fewer than 8 bits of entropy per character (~6.23 bits/character for its 75-character alphabet, vs. 8 for a raw byte), the password is longer than New-SecretSharingSecret's 16/32 bytes - long enough that its total entropy is at least the requested Entropy value, rounded up to an even character count (Split-SecretSharingSecret requires an even byte count). .PARAMETER Entropy The minimum entropy of the generated password, in bits. Must be 128 or 256, matching New-SecretSharingSecret's supported levels. .EXAMPLE PS> $password = New-SecretSharingPassword -Entropy 128 PS> Split-SecretSharingSecret -Secret $password -Group @{ Threshold = 3; Count = 5 } Generates a typeable password with at least 128 bits of entropy and splits it into 5 shares, any 3 of which reconstruct the exact same password. .OUTPUTS System.Security.SecureString #> [CmdletBinding()] [OutputType([System.Security.SecureString])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Pure in-memory computation (random bytes); no external state is changed.')] param( [Parameter(Mandatory)] [ValidateSet(128, 256)] [int]$Entropy ) $constant = Get-SecretSharingPasswordConstant $bitsPerCharacter = [Math]::Log($constant.Alphabet.Length, 2) $characterCount = [int][Math]::Ceiling($Entropy / $bitsPerCharacter) if ($characterCount % 2 -ne 0) { $characterCount++ } $passwordByte = Get-SecretSharingRandomAlphabetByte -Alphabet $constant.Alphabet -Length $characterCount return ConvertTo-SecretSharingSecureString -Byte $passwordByte } |